如何在R语言中从列表获取唯一的DataFrame?
从包含重复DataFrame的列表中提取唯一元素
我有一个包含重复DataFrame的列表,其中仅存在2个唯一的DataFrame:
library("tibble") dfy <- list( tibble( x=1:10, y=x*2 ), tibble( x=1:10, y=x*2 ), tibble( x=1:10, y=3*x ), tibble( x=1:10, y=x*2 ), tibble( x=1:10, y=3*x ) )
需求是从这个初始列表中得到仅包含2个唯一DataFrame的输出列表。
针对列表元素为向量的基础去重方法在此场景下无效,因为DataFrame不能作为向量元素:
x <- list(a=c(1,2,3), b = c(2,3,4), c=c(4,5,6)) unique(unlist(x))
你的循环方案存在的问题
你的循环代码有几个关键错误:
lgl向量索引错误:内层循环中用lgl[x]赋值,但x是外层循环的当前索引(从2开始递增),而uni的长度远小于x,导致lgl被填充大量NA,后续all(lgl)==FALSE的判断完全失效。uni列表索引错误:添加新元素时用uni[[x]] <- dfy[[x]],会导致uni出现大量空位置,最终列表长度和原列表一致,无法得到仅含唯一元素的列表。- 逻辑判断的隐性失效:虽然
all(lgl)==FALSE的逻辑本身正确(所有比较都为假时添加),但前面的索引错误导致无法正确识别元素是否已存在。
修正后的循环代码
uni <- list() for (df in dfy) { # 检查当前DataFrame是否已存在于uni中 is_duplicate <- any(sapply(uni, function(u) identical(df, u))) if (!is_duplicate) { uni <- c(uni, list(df)) } } # 查看结果 uni
其他更简洁的解决思路
方法1:直接使用purrr包的unique()函数
tibble和purrr原生支持列表中DataFrame的去重,一行代码即可解决:
library(purrr) unique_dfy <- unique(dfy)
方法2:用dplyr合并拆分法
先将列表合并为单个DataFrame,去重后再拆分为列表:
library(dplyr) unique_dfy <- bind_rows(dfy, .id = "source") %>% distinct(x, y, .keep_all = TRUE) %>% select(-source) %>% group_split(.keep = FALSE)
方法3:用duplicated生成重复标识
通过自定义逻辑生成每个元素的重复判断向量,再筛选唯一元素:
# 生成每个元素是否为重复项的逻辑向量 is_dup <- sapply(seq_along(dfy), function(i) { any(sapply(1:(i-1), function(j) identical(dfy[[i]], dfy[[j]]))) }) # 提取非重复元素 unique_dfy <- dfy[!is_dup]
内容的提问来源于stack exchange,提问作者szaki
相关产品推荐
相关产品推荐

