如果一个数据集中缺少,请使用给定名称创建一个空列

时间:2019-07-02 06:05:56

标签: r dataframe

我有5个数据集,每个数据集包含一些列。数据集具有通用的列名,但并非所有数据集中都存在所有列。因此,只要某个列名称(至少出现在数据集中的一个列中)不存在于其他某些数据集中,我就想用该数据集中的那个列名称创建一个全零的列。这样所有数据集都具有相同的列数(和相同的列名)。

4 个答案:

答案 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)