2012-11-12 41 views
1

我试图ddply使用我的样本数据(称之为Z)看起来像如下:使用lapply和ddply功能

id y 
1001 10 
1001 11 
1200 12 
2001 10 
2030 12 
2100 32 
3100 10 
3190 13 
4100 45 
5100 67 
5670 56 
... 
10001 54 
10345 45 
11234 32 
and so on 

我的目的是找到y的总和为ID出发1(即1001,1200,...),2(2100),3(3100,3190),4,... 10,11,... 65。例如,对于ID从1开始,总和为10 + 11 + 12 = 33,为ID从2开始,它是32

我想使用应用函数看起来像如下:

>s <- split(z,z$id) 
>lapply(s, function(x) colSums(x[, c("y")])) 

但是,这给了我每个唯一的ID,而不是我正在寻找的总和。任何有关这方面的建议将不胜感激。

+0

当然对于'2' - '(2001,2030,2100)'的总和将是'10 + 12 + 32 = 54'? – thelatemail

+0

你真的使用'ddply'吗?或者是一个错字? – mnel

回答

3

thelatemail提供了一个有效的方法,但我想指出问题并不在于你对lapply(你的代码几乎是正确的)的理解,而是想到了分组。 thelatemail在他的解决方案中这样做,这是关键。我要你用你的方法,然后展示如何将实际接近这一点,然后用ave只是因为我从来没有在数据使用它:)

z <- read.table(textConnection("id y #stole this from the latemail 
1001 10 
1001 11 
1200 12 
2001 10 
2030 12 
2100 32 
3100 10 
3190 13 
4100 45 
5100 67 
5670 56 
10001 54 
10345 45"),header=TRUE) 

你代码调整

s <- split(z, substring(as.character(z$id), 1, nchar(as.character(z$id)) - 3)) 
lapply(s, function(x) sum(x[, "y"])) 

方法我可能会拿;添加一个新的因子id变量

z$IDgroup <- substring(as.character(z$id), 1, nchar(as.character(z$id)) - 3) 
aggregate(y ~ IDgroup, z, sum) 
#similar approach but adds the solution back as a new column 
z$group.sum <- ave(z$y, z$IDgroup, FUN=sum) 
z 
+1

+ +1为解释更多的事情(和引用我:-)。让我意识到我的手柄在引用时听起来有多可怕。 – thelatemail

+0

太棒了!四种方法来做同样的事情。谢谢泰勒! – Metrics

3

这是否给你预期的答案?

z <- read.table(textConnection("id y 
1001 10 
1001 11 
1200 12 
2001 10 
2030 12 
2100 32 
3100 10 
3190 13 
4100 45 
5100 67 
5670 56 
10001 54 
10345 45"),header=TRUE) 

result <- tapply(
       z$y, 
       as.numeric(substr(z$id,1,nchar(z$id)-3)), 
       sum 
       ) 

result 
    1 2 3 4 5 10 
33 54 23 45 123 99 

窃取上述@ MNEL的线,这可以简化为:

result <- tapply(
       z$y, 
       z$id %/% 1000, 
       sum 
       ) 
+0

是的,它确实有效。感谢thelatemail。 – Metrics

5

这里是一个data.table的解决方案,使用%/%执行整数除法(返回多少万)

library(data.table) 
DT <- data.table(z) 

x <- DT[,list(sum_y = sum(y)), by = list(id = id %/% 1000)] 
x 
    id sum_y 
1: 1 33 
2: 2 54 
3: 3 23 
4: 4 45 
5: 5 123 
6: 10 99 

您可以用类似ddply

ddply(z, .(id = id %/% 1000), summarize, sum_y = sum(y)) 
    id sum_y 
1 1 33 
2 2 54 
3 3 23 
4 4 45 
5 5 123 
6 10 99 
+0

感谢mnel.It工作... – Metrics