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

aiqt4smr  于 2023-05-26  发布在  其他
关注(0)|答案(4)|浏览(152)

我有一个包含许多 Dataframe 的列表:

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轻松地在列表中找到 Dataframe 的列名:

lapply(my_list, colnames)

是否有方法确定列名中是否存在任何差异?我意识到这是一个涉及成对比较的复杂问题。

vngu2lb8

vngu2lb81#

您可以通过简单地检查每个列名的计数是否为== length(my_list)来避免成对比较。这将同时检查 Dataframe 的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))
yquaqz18

yquaqz182#

下面是另一个使用Reducebase解决方案:

!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()在列表中累积。首先,计算identical(names_df1, names_df2)。如果它为真,我们希望它返回相同的向量评估!然后我们可以继续使用它来与列表中的其他成员进行比较。
最后,如果所有值都为true,我们将返回一个字符向量。由于您可能需要一个逻辑输出,因此使用!is.logical(...)将该字符向量转换为布尔值。
也可以在这里看到,因为我很受另一个帖子的启发:
check whether all elements of a list are in equal in R
在我的编辑之后,我看到了一个类似的:
Test for equality between all members of list

hiz5n14c

hiz5n14c3#

我们可以使用dplyr::bind_rows

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

 # [1] FALSE
hujrc8aj

hujrc8aj4#

以下是我的回答:

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)

相关问题