对行和列进行平均,允许NA

时间:2012-09-19 11:47:09

标签: r

我的数据框如下所示:

> df
  id u.1t u.2 v.1 v.2
1  A    1  NA   5  NA
2  A    2  NA   4   6
3  A    1   4   5  NA
4  B   10  13  40  NA
5  B   10  12  42  NA
6  B   10  NA  41  NA

我希望分别了解idu.*列的v.*具体方法:

> mean
  id u.mean v.mean
1  A      2      5
2  B     11     41

这是数据

df<-data.frame(id=c("A","A","A","B","B","B"),u.1t=c(1,2,1,10,10,10),u.2=c(NA,NA,4,13,12,NA),v.1=c(5,4,5,40,42,41),v.2=c(NA,6,NA,NA,NA,NA))

很明显,通过引入NA,总体平均值不等于行或列均值的平均值,这就是问题所在。

我认为这是by的工作,但事实证明除了按列操作我无法做by做任何事情?

非常感谢帮助 - 谢谢

2 个答案:

答案 0 :(得分:5)

如果您想使用by,请尝试以下方法:

by(x, x$id, function(x) colMeans(x[,-1], na.rm=TRUE))

输出有点难看。虽然你可以整理一下,但我会使用plyr包:

library(plyr)
ddply(x, .(id), function(x) colMeans(x[,-1], na.rm=TRUE))

这并不能完全实现您的目标,因为它需要每列的平均值:它不会合并u.*v.*列。为此,我首先melt数据,然后使用plyr

library(reshape2)
y <- melt(x)
y$variable <- gsub("\\..*", '', y$variable)
y
#   id variable value
#1   A        u     1
#2   A        u     2
#3   A        u     1
#4   B        u    10
#5   B        u    10
#6   B        u    10
#7   A        u    NA
#    (etc)

z <- ddply(y, .(id, variable), summarise, mean = mean(value, na.rm=TRUE))
z
#  id variable mean
#1  A        u    2
#2  A        v    5
#3  B        u   11
#4  B        v   41

如果您选择,可以cast返回:

dcast(z, id~variable)
#  id  u  v
#1  A  2  5
#2  B 11 41    

答案 1 :(得分:0)

肖恩说得对。他的解决方案很完美。

但是,由于变量名称中的模式替换通常不方便,不适用(在我的情况下 - 不是示例),或者根本不是每个人的一杯茶,人们不妨引入一个新因素来区分{来自u's的{​​1}}。 v's立即给出答案(不需要cast):

plyr

甚至无需考虑新创建的列require(reshape2) y<-melt(df) y$x[y$variable %in% c("u.1t","u.2")]<-"u" y$x[y$variable %in% c("v.1","v.2")]<-"v" y # id variable value x #1 A u.1t 1 u #2 A u.1t 2 u #3 A u.1t 1 u #4 B u.1t 10 u #5 B u.1t 10 u # ... #22 B v.2 NA v #23 B v.2 NA v #24 B v.2 NA v dcast(y,y$id~x,mean, na.rm=T) # y$id u v #1 A 2 5 #2 B 11 41

y$x