R:用NA计算人口标准差

时间:2016-07-17 07:05:32

标签: r

由于sd计算样本标准差,而非人口标准差,我必须编写一个函数来获得总体标准差。

如果没有NA,可以轻松完成,如下所示。

> set.seed(1)
> mf1<-matrix(sample(c(10:100),18, replace=T),ncol=3)
> mf1
     [,1] [,2] [,3]
[1,]   34   95   72
[2,]   43   70   44
[3,]   62   67   80
[4,]   92   15   55
[5,]   28   28   75
[6,]   91   26  100
> pop.sd<-function(x){sqrt(sum((x-mean(x))^2)/length(x))}
> apply(mf1,1,pop.sd)
[1] 25.152866 12.498889  7.586538 31.443070 22.156012 32.967998

但是,当存在NA时,该函数返回相应行的NA。

> mf2<-mf1
> mf2[c(2,5),3]<-NA
> mf2
     [,1] [,2] [,3]
[1,]   34   95   72
[2,]   43   70   NA
[3,]   62   67   80
[4,]   92   15   55
[5,]   28   28   NA
[6,]   91   26  100
> apply(mf2, 1, pop.sd)
[1] 25.152866        NA  7.586538 31.443070        NA 32.967998

你能帮助我让这个函数允许NAs,这样我也可以为第2行和第5行写一些数字吗?

感谢。

1 个答案:

答案 0 :(得分:1)

我们可以使用na.rm=TRUEmean中的sum来说明NA元素。

pop.sd<-function(x){sqrt(sum((x-mean(x, na.rm=TRUE))^2, 
                                 na.rm=TRUE)/sum(!is.na(x)))}
apply(mf2, 1, pop.sd)
#[1] 25.152866 13.500000  7.586538 31.443070  0.000000 32.967998

这也应该为&#39; mf1&#39;

提供相同的结果
apply(mf1,1,pop.sd)
#[1] 25.152866 12.498889  7.586538 31.443070 22.156012 32.967998

我们还可以使用矢量化rowSumsrowMeans

来代替循环行。
sqrt(rowSums((mf1-rowMeans(mf1, na.rm=TRUE))^2, na.rm=TRUE)/ncol(mf1))
#[1] 25.152866 12.498889  7.586538 31.443070 22.156012 32.967998

sqrt(rowSums((mf2-rowMeans(mf2, na.rm=TRUE))^2, na.rm=TRUE)/ncol(mf2))
#[1] 25.152866 11.022704  7.586538 31.443070  0.000000 32.967998