在R中聚合缺失值

4

在计算聚合平均值时,我遇到了处理NAs的问题。请看下面的代码:

tab=data.frame(a=c(1:3,1:3), b=c(1,2,NA,3,NA,NA))
tab
  a  b
1 1  1
2 2  2
3 3 NA
4 1  3
5 2 NA
6 3 NA

attach(tab)
aggregate(b, by=list(a), data=tab, FUN=mean, na.rm=TRUE)
  Group.1   x
1       1   2
2       2   2
3       3 NaN

如果向量中所有值都是NA,则我希望输出为NA,而不是NaN。
  Group.1   x
1       1   2
2       2   2
3       3  NA

我尝试使用自定义函数:

adjmean=function(x) {if(all(is.na(x))) NA else mean(x,na.rm=TRUE)}

然而,我遇到了以下错误:
aggregate(b, by=list(a), data=tab, FUN=adjmean)

Error in FUN(X[[1L]], ...) : 
  unused argument (data = list(a = c(1, 2, 3, 1, 2, 3), b = c(1, 2, NA, 3, NA, NA)))

简而言之,如果列中全部为NAs,则输出NA而不是NaN。如果只有少量NAs,则应该在忽略NAs的情况下计算平均值。
任何帮助都将不胜感激。
谢谢。

1
你在这里使用attach有什么原因吗?或者是将它与data = tab结合使用? - David Arenburg
@DavidArenburg,他们混淆了aggregate的公式方法和基本方法。默认(非公式)方法没有data参数,因此需要使用attachwith$ - A5C1D2H2I1M1N2O1R2T1
2个回答

6

这与您之前的内容非常接近,但是使用了一个自定义函数来替换mean(x, na.rm=TRUE),该函数可以计算非NA值的平均值,或提供NA本身:

R> with(tab, 
        aggregate(b, by=list(a), FUN=function(x) 
             if (any(is.finite(z<-na.omit(x)))) mean(z) else NA))
  Group.1  x
1       1  2
2       2  2
3       3 NA
R> 

这实际上只是一行代码,但我将其分开以适应 SO 显示。

而且您已经有了相似的想法,但我进一步修改了该函数以在所有情况下返回合适的值。


非常感谢你,Dirk...我发现你的语法也可以很好地与我的函数配合使用...即 with(tab, aggregate(b, by=list(a), FUN=adjmean)) 可以正常工作...不知道为什么这里使用聚合函数的其他语法不起作用... - Abhirup Datta
欢迎。请随意_接受_(仅您作为问题所有者才能看到勾号)和/或_点赞_(点击上三角形)--- 这就是StackOverflow的工作方式。 - Dirk Eddelbuettel
2
@DirkEddelbuettel,抱歉,但是他们的函数并没有什么明显的问题 - A5C1D2H2I1M1N2O1R2T1

3

您的函数没有问题。问题在于您正在使用aggregate的默认方法中不存在的参数:

adjmean = function(x) {if(all(is.na(x))) NA else mean(x,na.rm=TRUE)}
attach(tab)  ## Just because you did it. I don't recommend this.

## Your error
aggregate(b, by=list(a), data=tab, FUN=adjmean)
# Error in FUN(X[[i]], ...) : 
#   unused argument (data = list(a = c(1, 2, 3, 1, 2, 3), b = c(1, 2, NA, 3, NA, NA)))

## Dropping the "data" argument
aggregate(b, list(a), FUN = adjmean)
#   Group.1  x
# 1       1  2
# 2       2  2
# 3       3 NA

如果您想使用数据参数,则应该使用聚合的公式方法。然而,这种方法对缺失值的处理方式有所不同,因此您需要一个额外的参数。

示例:

detach(tab) ## I don't like having things attached
aggregate(b ~ a, data = tab, adjmean)
#   a b
# 1 1 2
# 2 2 2
aggregate(b ~ a, data = tab, adjmean, na.action = na.pass)
#   a  b
# 1 1  2
# 2 2  2
# 3 3 NA

感谢 Ananda 解释这个。 - Abhirup Datta

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