有没有一种简单的方法来判断存储在一个列表中的许多数据帧是否包含相同的列?

时间:2019-06-29 23:44:16

标签: r lapply

我有一个包含许多数据帧的列表:

df1 <- data.frame(A = 1:5, B = 2:6, C = LETTERS[1:5])
df2 <- data.frame(A = 1:5, B = 2:6, C = LETTERS[1:5])
df3 <- data.frame(A = 1:5, C = LETTERS[1:5])
my_list <- list(df1, df2, df3)

我想知道此列表中的每个数据框是否包含相同的列(即,相同数量的列,它们的名称和顺序相同)。

我知道您可以使用lapply在列表中轻松找到数据框的列名:

lapply(my_list, colnames)

是否可以确定列名称是否发生任何差异?我意识到这是一个涉及成对比较的复杂问题。

4 个答案:

答案 0 :(得分:2)

您可以通过简单地检查每个列名的计数是否为== length(my_list)来避免成对比较。这将同时检查您数据帧中的dimnames-

lapply(my_list, names) %>%
  unlist() %>% 
  table() %>% 
  all(. == length(my_list))

[1] FALSE

在基本R中,即没有%>%-

all(table(unlist(lapply(my_list, names))) == length(my_list))

[1] FALSE

或者明显更优化-

!any(table(unlist(lapply(my_list, names))) != length(my_list))

答案 1 :(得分:1)

我们可以使用dplyr::bind_rows

!any(is.na(dplyr::bind_rows(my_list)))

 # [1] FALSE

答案 2 :(得分:1)

这是另一个base的{​​{1}}解决方案:

Reduce

您还可以使用

以不同的顺序说明相同的列
!is.logical(
  Reduce(function(x,y) if(identical(x,y)) x else FALSE
         , lapply(my_list, names)
         )
)

关于正在发生的事情,!is.logical( Reduce(function(x,y) if(identical(x,y)) x else FALSE , lapply(my_list, function(z) sort(names(z))) ) ) 在列表中累积。首先,对Reduce()进行评估。如果是真的,我们希望它返回评估的相同向量!然后,我们可以继续使用它与列表中的其他成员进行比较。

最后,如果所有结果都为true,则返回一个字符向量。由于您可能需要逻辑输出,因此使用identical(names_df1, names_df2)将字符向量转换为布尔值。

另请参阅此处,因为我受到另一篇文章的启发:

check whether all elements of a list are in equal in R

还有我编辑后看到的类似图片:

Test for equality between all members of list

答案 3 :(得分:0)

这是我的答案:

k <- 1
output <- NULL
for(i in 1:(length(my_list) - 1)) {
 for(j in (i + 1):length(my_list)) {
  output[k] <- identical(colnames(my_list[[i]]), colnames(my_list[[j]]))
  k <- k + 1
 }
}
all(output)