使用lapply和ddply函数

时间:2012-11-12 04:45:28

标签: r apply

我正在尝试将ddply用于我的示例数据(调用Z),如下所示:

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

我的目的是找到以1开头的id的总和(ie1001,1200,..),2(2100),3(3100,3190),4,... 10,11, ... 65。例如,对于以1开头的id,总和为10 + 11 + 12 = 33,对于以2开头的id,它为32.

我想使用如下所示的apply函数:

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

但是,这给了我每个唯一ID的总和,而不是我想要的那个。任何有关这方面的建议都将受到高度赞赏。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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
                )

答案 2 :(得分: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