2015-04-26 53 views
3

我在计算汇总均值时处理NAs时遇到问题。请看下面的代码:R中的总计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,而不是NaN的,如果向量具有所有NAS,即我所要的输出是

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))) 

简而言之,如果列中有所有的NA,我希望将NA作为输出而不是NaN。如果它的NAs很少,那么它应该计算忽略NAs的平均值。

任何帮助,将不胜感激。

感谢

+1

您正在使用的任何理由'这里attach'?或者将它与'data = tab'结合使用? –

+0

@DavidArenburg,他们正在混合“聚合”的公式方法和基本方法。默认(非公式)方法没有'data'参数,因此需要'attach','with'或'$'。 – A5C1D2H2I1M1N2O1R2T1

回答

5

这是非常接近,你有什么,但是这两种计算非NA值的平均值的自定义函数替换mean(x, na.rm=TRUE),或提供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显示。

你已经有了一个类似的想法,但我更改了一些函数来返回所有情况下的合适值。

+0

非常感谢Dirk ...我发现你的语法和我的函数一起工作的很好...即(tab,aggregate(b,by = list(a),FUN = adjmean)使用聚合的其他语法在这里不起作用... –

+0

不客气。请随意使用_accept_(点击只有你自己作为问题的所有者)和/或_upvote_(点击向上三角形)---这就是StackOverflow的工作原理。 –

+2

@DirkEddelbuettel,对不起,但有[没有什么完全错误的功能](http://stackoverflow.com/a/29873855/1270695).... – 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 

如果你想用data说法,你应该使用formula方法aggregate。但是,此方法对待NA的方式不同,因此您需要额外的参数na.action

例子:

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 
+0

谢谢阿南达解释这个 –