如何用dplyr对含NA的三个变量按行取均值生成新变量
解决R语言中按行计算多列均值(含NA值)的问题
嘿,我来帮你搞定这个问题!你遇到的错误其实是因为对mean()函数的用法和dplyr管道的逻辑理解有点偏差,咱们一步步拆解并解决:
错误原因分析
- 首先,
mean()函数的参数设计是第一个参数是要计算均值的向量,第二个参数trim是用来指定截尾比例的单个数值,你直接把三个列向量传进去,R会把第二个列(Ozone)当成trim参数,这就触发了'trim' must be numeric of length one的错误——毕竟Ozone是一整列数据,不是单个数值。 - 其次,在dplyr的管道(
%>%)里,没必要写airquality$Solar.R这种全称,管道已经把数据框传递过来了,直接用列名就行。 - 最后,
mean()默认是计算整个向量的整体均值,而你需要的是每行的均值,这得用专门的行级计算方法。
正确解法
方法1:用rowMeans()(最简洁高效)
rowMeans()是R内置的专门计算行均值的函数,原生支持处理NA值,写法非常简洁:
library(dplyr) airquality %>% mutate(New = rowMeans(select(., Solar.R, Ozone, Wind), na.rm = TRUE))
select(., Solar.R, Ozone, Wind):在管道中选中需要计算的三列(.代表当前管道传递的数据框)na.rm = TRUE:忽略每行中的NA值,如果某一行三个值都是NA,结果会返回NA
方法2:用dplyr的rowwise() + c_across()(tidyverse风格,适合复杂行计算)
如果你需要更灵活的行级操作(比如除了均值还要做其他行内计算),可以用这种写法:
library(dplyr) airquality %>% rowwise() %>% # 告诉dplyr接下来的计算按行执行 mutate(New = mean(c_across(Solar.R:Wind), na.rm = TRUE)) %>% # c_across把指定列按行打包成向量 ungroup() # 记得取消行分组,避免后续操作受影响
关于你尝试的filter的补充
你之前用filter的写法也有问题:is.na()只能接收单个向量,要筛选出三列都不为NA的行,应该这么写:
airquality %>% filter(if_all(c(Solar.R, Ozone, Wind), ~!is.na(.x)))
不过其实如果只是计算均值的话,不需要提前过滤,na.rm = TRUE已经能处理NA值了,保留所有行的结果会更完整。
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

