Связать столбцы с разным количеством строк
Я хочу создать итерацию, которая берет список (который является столбцом другого фрейма данных) и добавляет его к текущему фрейму данных в качестве столбца. но длина столбцов не равна. Итак, я хочу создать 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
является новым из добавленного столбца.