Связать столбцы с разным количеством строк

Я хочу создать итерацию, которая берет список (который является столбцом другого фрейма данных) и добавляет его к текущему фрейму данных в качестве столбца. но длина столбцов не равна. Итак, я хочу создать NA как несопоставленные строки.

seq_actions=as.data.frame(x = NA)
for(i in 1:20){
  temp_seq=another_df$c1[some conditions]  
  seq_actions=cbind(temp_seq,seq_actions)
}

чтобы упростить, скажем, у меня есть

df
1  3
3  4
2  2

добавив список 5,6 в качестве нового столбца в df, поэтому я хочу:

 df
    1  3  5
    3  4  6
    2  2  NA

другой список добавления - 7 7 7 8, поэтому мой df будет:

df
   1  3  5  7
   3  4  6  7
   2  2  NA 7
   NA NA NA 8

Как мне это сделать?

4 ответа

Решение

Вот один из способов. Функция слияния по своей структуре будет добавлять значения NA, когда вы объединяете фреймы данных, и совпадение не найдено (например, если у вас меньше значений в 1 фрейме данных, чем в другом фрейме данных).

Если вы предполагаете, что сопоставляете свои фреймы данных (какие строки объединяются) на основе номера строки, просто выведите номер строки в виде столбца в ваших фреймах данных. Затем объедините этот столбец. Merge автоматически добавит нужные вам значения NA и будет учитывать тот факт, что кадры данных имеют разное количество строк.

#test data frame 1
a <- c(1, 3, 2)
b <- c(3, 4, 2)
dat <- as.data.frame(cbind(a, b))

#test data frame 2 (this one has fewer rows than the first data frame)
c <- c(5, 6)
dat.new <- as.data.frame(c)

#add column to each data frame with row number
dat$number <- row.names(dat)
dat.new$number <- row.names(dat.new)

#merge data frames
#"all = TRUE" will mean that NA values will be added whenever there is no match 
finaldata <- merge(dat, dat.new, by = "number", all = TRUE)

Если вам известен максимально возможный размер df и общее количество столбцов, которые вы хотите добавить, вы можете заранее создать df со всеми значениями NA и заполнить столбец в зависимости от его длины. Это оставило бы все после его длины все еще NA.

например

max_col_num <- 20 
max_col_size <- 10 #This could be the number of rows in the largest dataframe you have

df <- as.data.frame(matrix(ncol = max_col_num, nrow = max_col_size))

for(i in 1:20){
      temp_seq=another_df$c1[some conditions] 
      df[c(1:length(temp_seq), i] <- temp_seq
}

Это будет работать только в том случае, если вы введете общее возможное количество строк и столбцов.

Я думаю, что лучше всего написать собственную функцию, основанную на nrow фрейма данных и length вектора / список.

Однажды такую ​​функцию можно записать так:

#Function to add vector as column
addToDF <- function(df, v){
 nRow <- nrow(df)
 lngth <- length(v)
 if(nRow > lngth){
   length(v) <- nRow
 }else if(nRow < lngth){
   df[(nRow+1):lngth, ] <- NA
 }
 cbind(df,v)
}

Давайте проверим вышеуказанную функцию с помощью data.frame, предоставленного OP.

df <- data.frame(A= c(1,3,2), B = c(3, 4, 2))

v <- c(5,6)

w <-c(7,7,8,9)

addToDF(df, v)
#   A B  v
# 1 1 3  5
# 2 3 4  6
# 3 2 2 NA

addToDF(df, w)
#    A  B v
# 1  1  3 7
# 2  3  4 7
# 3  2  2 8
# 4 NA NA 9

После ответа MKR, если вы хотите добавить конкретное имя в новый добавленный столбец, вы можете попробовать:

      
addToDF <- function(df, v, col_name){
  nRow <- nrow(df)
  lngth <- length(v)
  if(nRow > lngth){
    length(v) <- nRow
  }else if(nRow < lngth){
    df[(nRow+1):lngth, ] <- NA
  }
  df_new<-cbind(df,v)
  colnames(df_new)[ncol(df_new)]=col_name
  return(df_new)
}

где col_name является новым из добавленного столбца.

Другие вопросы по тегам