从data.frame列表中选取维度最大的对象(tidyverse方案)
解决方案:从data.frame列表中选取元素总数最大的data.frame
更简洁的tidyverse实现(含purrr::keep的单行逻辑)
你可以直接在keep中结合map_dbl预先计算所有data.frame的元素总数,一步完成筛选:
library(tidyverse) dfinal <- dflist %>% keep(~ nrow(.) * ncol(.) == (dflist %>% map_dbl(~ nrow(.) * ncol(.)) %>% max())) %>% pluck(1)
如果追求更高效率(适配近百个data.frame的场景),建议先一次性计算所有元素总数,再通过索引提取,避免重复计算维度:
# 一次性计算所有data.frame的元素总数 sizes <- dflist %>% map_dbl(~ nrow(.) * ncol(.)) # 提取对应最大值的data.frame dfinal <- dflist[[which.max(sizes)]]
关于元素总数的高效计算方式
你提到的reduce(dim(.), *)可以简化为更直接的nrow(df) * ncol(df)——这是R中计算data.frame元素总数的标准写法,效率更高:
nrow()和ncol()是专门针对数据框的维度函数,底层实现更轻量化;length(unlist(df))会先将数据框转为向量,额外增加内存开销,若数据框包含列表列还会出现结果偏差;reduce(dim(...),*)本质和nrow*ncol逻辑一致,但多了一层reduce调用,效率略低。
示例验证
用你提供的测试数据运行上述代码,可正确返回元素总数最大的data.frame:
# 生成示例数据 df <- data.frame( id = c(1,2,3,4,5,6,7,8,9,10), c1 = c("a", "a", "c", NA, "c", "d", "c", NA, "a", "b"), c2 = c(25, NA, 17, 5, 50, 43, 21, 2, 1, NA), c3 = c(NA, "s", "r", NA, "r", "i", NA, "r", NA, NA), c4 = c(1.0, 5.3, 2.9, NA, 6.1, NA, 2.5, 4.3, 9.1, 2.4), c5 = c(5, 6, NA, 3, 1, 6, 7, 8, 2, 1) ) cols2drop <- c("c2", "c3", "c4", "c5") dflist <- cols2drop %>% map(~ df %>% select(1:.x) %>% drop_na()) # 测试高效实现 sizes <- dflist %>% map_dbl(~ nrow(.) * ncol(.)) dfinal <- dflist[[which.max(sizes)]] dim(dfinal) # 查看结果维度
内容的提问来源于stack exchange,提问作者Amy M
相关产品推荐
相关产品推荐

