2014-12-04 160 views
0

我有一个数据帧像这样:如何计算按组的观察值?

mydf <- data.frame(group=c(rep("a", 4),rep("b", 4), rep("c", 4)), score=sample(1:10, 12, replace=TRUE)) 
mydf 
    group score 
1  a 10 
2  a  9 
3  a  2 
4  a  3 
5  b  1 
6  b 10 
7  b  1 
8  b 10 
9  c  3 
10  c  7 
11  c  1 
12  c  3 

我可以计算出平均每一批像这样:

> by(mydf[,c("score")], mydf$group, mean) 
mydf$group: a 
[1] 6 
------------------------------------------------------------------- 
mydf$group: b 
[1] 5.5 
------------------------------------------------------------------- 
mydf$group: c 
[1] 3.5 

但是我希望做的,是创建一个新的专栏,说叫其中包含来自组的平均值的残差。似乎有一种方法可以使用apply函数之一来执行此操作,但出于某种原因我无法看到它。

我想我最终的结果看起来像这样:

mydf 
    group score residual 
1  a 10  4 
2  a  9  3 
3  a  2  -4 
4  a  3  -3 
5  b  1  -4.5 
6  b 10  4.5 
7  b  1  -4.5 
8  b 10  4.5 
9  c  3  -.5 
10  c  7  3.5 
11  c  1  -2.5 
12  c  3  -.5 

任何意见或指向正确的方向表示赞赏。

+0

使用'sample'或'runif','dunif'等函数时,事先使用'set.seed'好,结果是可以复制的。 – Tim 2014-12-04 23:27:00

+0

是的,你可能想修复你的例子,意思是(c(10,9,7,9))== 6? – thelatemail 2014-12-04 23:30:13

+0

谢谢,我已更正我的数据对不起,因为不使用随机种子 – 2014-12-05 04:28:48

回答

2

如何:

mydf$score - tapply(mydf$score, mydf$group, mean)[as.character(mydf$group)] 

tapply的工作方式相同by但有更好的输出。 [as.character(mydf$group)]子集和复制tapply的输出使它对齐mdf$group

+1

'(mydf,score-ave(score,group))'会比'tapply'更容易,因为组变量的顺序无关紧要。 – thelatemail 2014-12-04 23:31:10

+0

这是'ave'some!我从来没有对这个功能感到困扰。 – Tim 2014-12-04 23:37:58

+0

我的最爱之一。这实际上是许多d/plyr函数使用的“分裂应用合并”逻辑。 – thelatemail 2014-12-04 23:48:17

2
library(dplyr) 
mydf %>% group_by(group) %>% mutate(residual = score - mean(score)) 

予取数据,I组由group,然后我添加一列(使用mutate),它是可变score并且每个组中的变量的均值之间的差。

0
library(hash) 
mydf <- data.frame(group=c(rep("a", 4),rep("b", 4), rep("c", 4)), score=sample(1:10, 12, replace=TRUE)) 
byResult <- by(mydf[,c("score")], mydf$group, mean) 
h <- hash(keys= names(byResult), values =byResult) 
residualsVar <- apply(mydf,1,function(row){ 
as.vector(values(h,row[1]))-as.numeric(row[2]) 
}) 
df <- cbind(mydf,residualsVar)