我有5个数据集,每个数据集包含一些列。数据集具有通用的列名,但并非所有数据集中都存在所有列。因此,只要某个列名称(至少出现在数据集中的一个列中)不存在于其他某些数据集中,我就想用该数据集中的那个列名称创建一个全零的列。这样所有数据集都具有相同的列数(和相同的列名)。
答案 0 :(得分:1)
将数据框放入列表中,获取所有合并的数据框中存在的所有unique
列名称,并添加每个数据框中不存在的列(为0)。
all_names <- unique(unlist(sapply(list_df, names)))
lst1 <- lapply(list_df, function(x) {x[setdiff(all_names, names(x))] <- 0;x})
lst1
#[[1]]
# a b c
#1 1 6 0
#2 2 7 0
#3 3 8 0
#4 4 9 0
#5 5 10 0
#[[2]]
# a c b
#1 1 6 0
#2 2 7 0
#3 3 8 0
#4 4 9 0
#5 5 10 0
#[[3]]
# a c b
#1 1 6 11
#2 2 7 12
#3 3 8 13
#4 4 9 14
#5 5 10 15
如果需要单独的数据帧,则可以再次单独使用lst1[[1]]
和lst1[[2]]
。
数据
df1 <- data.frame(a = 1:5, b = 6:10)
df2 <- data.frame(a = 1:5, c = 6:10)
df3 <- data.frame(a = 1:5, c = 6:10, b = 11:15)
list_df <- list(df1, df2, df3)
答案 1 :(得分:1)
我们可以使用for
循环来完成
un1 <- Reduce(union, lapply(lst1, names))
for(i in seq_along(lst1)) lst1[[i]][setdiff(un1, names(lst1[[i]]))] <- 0
lst1 <- list(structure(list(a = 1:5, b = 6:10, c = c(0, 0, 0, 0, 0)),
row.names = c(NA,
-5L), class = "data.frame"), structure(list(a = 1:5, c = 6:10,
b = c(0, 0, 0, 0, 0)),
row.names = c(NA, -5L), class = "data.frame"),
structure(list(a = 1:5, c = 6:10, b = 11:15),
class = "data.frame", row.names = c(NA,
-5L)))
答案 2 :(得分:1)
我将使用dplyr的bind_rows
,它会使用NA自动填充缺失的值。如果包含.id = "df_id"
,则会添加一列,将每一行连接到原始数据框:
library(dplyr)
bind_rows(df1, df2, df3, .id = "df_id")
#### OUTPUT ####
df_id x y z
1 1 1 2 NA
2 2 3 NA 4
3 3 NA 5 6
如果您想要0而不是NA,则只需df[is.na(df)] <- 0
。如果您希望获得更丰富的df_id
列,可以传递一个命名列表:
bind_rows(list(df1 = df1, df2 = df2, df3 = df3), .id = "df_id")
#### OUTPUT ####
df_id x y z
1 df1 1 2 NA
2 df2 3 NA 4
3 df3 NA 5 6
如果您希望将数据帧分开,则只需用df_id
分割,即可生成数据帧列表:
df <- bind_rows(df1, df2, df3, .id = "df_id")
split(df, df$df_id)
#### OUTPUT ####
$`1`
df_id x y z
1 1 1 2 NA
$`2`
df_id x y z
2 2 3 NA 4
$`3`
df_id x y z
3 3 NA 5 6
df1 <- data.frame(x = 1, y = 2)
df2 <- data.frame(x = 3, z = 4)
df3 <- data.frame(y = 5, z = 6)
答案 3 :(得分:0)
除了前面的答案外,您还可以使用bind_rows
函数来快速组合所有数据框,这将解决列名之间的差异:
library(dplyr)
x <- data.frame(
a = 1:3,
b = 4:6
)
y <- data.frame(
a = 4:7
)
z <- data.frame(
c = 8:10
)
xyz <- bind_rows(x, y, z)
xyz %>% replace(., is.na(.), 0)