如何用R简洁实现按组统计数据框各列唯一值数量?
如何高效按分组统计数据框各列的唯一值数量?
需求说明:
有一个包含大量列的数据框,需按指定列分组,最终输出新的数据框/tibble——每行对应原数据框的一个分组,其余列的值为对应分组下该列的唯一值数量。限制条件:除分组列外,不能在脚本中显式引用其他列。
目前已通过for循环实现需求,但希望找到更高效、更符合R风格的实现方式。尝试过group_by()和嵌套apply()调用,但未得到预期结果。
示例数据与原有实现代码
# 实际数据框的列数远多于示例 df <- data.frame(my_group=c('a','b','c','a','b','c','a','b','c'), age=c(1,2,3,4,5,6,1,8,9), gender=c(1,1,2,2,1,2,2,2,2), x=c(T,F,F,T,F,T,F,F,F)) # 按分组拆分数据框 t <- split(df[,colnames(df)!="my_group"], df$my_group) results <- df[FALSE,] # 初始化结果模板 for ( i in 1:length(t)) { # 用for循环实现 z <- rapply(t[[i]], function(x) length(unique(unlist(x)))) row <- data.frame(my_group=names(t[i]),t(data.frame(z))) results <- rbind(results, row, make.row.names=FALSE) }
原有实现的输出
> results my_group age gender x 1 a 2 2 2 2 b 3 2 1 3 c 3 1 2 # 结果正确,但速度慢,不够"R风格"
高效优化方案
经过测试,以下三种方案最适用,其中第一种速度最快:
方案1(最快):
df %>% group_by(my_group) %>% summarise_all(n_distinct)贡献者:Samet Sökel
方案2(相对速度 1.12):
summarize(df, across(everything(), n_distinct), .by=my_group)贡献者:TarJae, Umar
方案3(相对速度 1.022):
aggregate(. ~ my_group, data = df, n_distinct)贡献者:AkselA, TarJae, Umar, Samet Sökel
注意事项
若数据框存在NA值,aggregate()方法会失效,即使设置na.action = na.omit也无法解决,使用时需谨慎。
内容的提问来源于stack exchange,提问作者Io Ferenghetti
相关产品推荐
相关产品推荐

