使用lapply和dplyr按分组列计算多列描述统计返回NA如何解决
问题原因
第一段代码报错原因
- 你传入
mean()/sd()的参数x是字符型的列名,noquote()仅修改打印时的展示效果,并没有将字符串转为数据框的对应列,本质还是在对字符串做数值计算,所以返回NA。 - 如果要通过字符型列名调用dplyr管道中的列,需要用tidyevaluation语法,比如
.data[[x]]或者!!rlang::sym(x)。
第二段across写法错误原因
across()的语法使用错误:你需要把要应用的多个汇总函数放在列表里传递给across的.fns参数,原来的写法把sd()、n()放在了across的参数外面,属于参数传递错误。- 注意:默认
n()统计的是分组的总行数,如果你需要统计每一列自身的非NA样本量,要替换为sum(!is.na(.)),适配你各列NA分布不同的需求。
解决方案
方案1:用across直接生成单张汇总表(更推荐)
输出为1个数据框,每一行对应1个分组,每一列对应「原数值列_统计量」的结果:
library(dplyr) iris %>% group_by(Species) %>% summarise( across( .cols = 1:4, # 也可以写where(is.numeric)自动匹配所有数值列 .fns = list( mean = ~mean(., na.rm = TRUE), sd = ~sd(., na.rm = TRUE), n = ~sum(!is.na(.)) ) ) )
方案2:保留你原来每个数值列单独返回数据框的需求
如果需要每个数值列对应一个独立的汇总数据框,和你最初lapply的输出逻辑一致:
library(dplyr) lapply(names(iris)[1:4], function(x) { iris %>% group_by(Species) %>% summarise( mean = mean(.data[[x]], na.rm = TRUE), sd = sd(.data[[x]], na.rm = TRUE), n = sum(!is.na(.data[[x]])) ) })
内容的提问来源于stack exchange,提问作者DTYK
相关产品推荐
相关产品推荐

