如何使用dplyr计算每行的平均值并处理缺失值

3

我希望能够对包含缺失值的数据框中的每一行进行多列均值计算,并将结果放入名为“means”的新列中。以下是我的数据框:

df <- data.frame(A=c(3,4,5),B=c(0,6,8),C=c(9,NA,1))
  A B  C
1 3 0  9
2 4 6 NA
3 5 8  1

如果列没有缺失值,例如列A和B,则下面的代码可以成功完成任务。
 library(dplyr)
 df %>%
 rowwise() %>%
 mutate(means=mean(A:B, na.rm=T))

     A     B     C   means
  <dbl> <dbl> <dbl> <dbl>
1     3     0     9   1.5
2     4     6    NA   5.0
3     5     8     1   6.5

然而,如果一列存在缺失值,例如C列,则会出现错误:
> df %>% rowwise() %>% mutate(means=mean(A:C, na.rm=T))
Error: NA/NaN argument

理想情况下,我希望使用dplyr实现。

3个回答

9
df %>% 
  mutate(means=rowMeans(., na.rm=TRUE))
. 是一个代词,指的是被传递到 mutate 中的数据框 df
  A B  C    means
1 3 0  9 4.000000
2 4 6 NA 5.000000
3 5 8  1 4.666667
您可以使用所有通常的方法(列名,索引,grep等)仅选择特定的列包含在内。
df %>% 
  mutate(means=rowMeans(.[ , c("A","C")], na.rm=TRUE))
  A B  C means
1 3 0  9     6
2 4 6 NA     4
3 5 8  1     3

太好了!rowwise()的帮助文档中说:“为了让你在summarise和mutate中能够使用列表变量而不必使用[[1]]。”然而,看起来没有办法避免使用方括号。 - Irakli
rowwise 也是出了名的慢。 - eipi10

3
在基础R中也很容易实现:
cbind(df, "means"=rowMeans(df, na.rm=TRUE))
  A B  C    means
1 3 0  9 4.000000
2 4 6 NA 5.000000
3 5 8  1 4.666667
rowMeans函数执行计算操作,同时允许使用na.rm参数跳过缺失值;cbind函数可以将平均值和任意名称绑定到数据框df中。

2

针对OP代码中的错误,我们可以使用连接函数c将这些元素作为单个vector获取,然后使用mean进行平均值计算,因为mean只能接受单个参数。

df %>%
    rowwise() %>% 
    mutate(means = mean(c(A, B, C), na.rm = TRUE))
#     A     B     C    means 
#  <dbl> <dbl> <dbl>    <dbl>
#1     3     0     9 4.000000
#2     4     6    NA 5.000000
#3     5     8     1 4.666667

此外,我们可以使用transformrowMeans
transform(df, means = rowMeans(df, na.rm = TRUE))
#  A B  C    means
#1 3 0  9 4.000000
#2 4 6 NA 5.000000
#3 5 8  1 4.666667

或者使用 data.table

library(data.table)
setDT(df)[, means := rowMeans(.SD, na.rm = TRUE)]

谢谢您解释这个错误,@akrun。使用rowwise()的回答非常优秀。但是对于大量列的范围,例如从A到Z,是否有一种方法可以在c函数中进行连接而不必逐个列出每个列? - Irakli
dplyrmutate内部,我发现其他选项无法正常工作,例如unlist等。因此,我会采用eipi10的解决方案,并使用rowMeans,因为它快速且使用了dplyr - akrun
1
这就是为什么我在 mutate 和 mean 方面遇到了很多麻烦的原因。谢谢你,@akrun! - Irakli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接