我正在尝试将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的总和,而不是我想要的那个。任何有关这方面的建议都将受到高度赞赏。
答案 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