R:累计计算列值出现在其他列中的次数

时间:2013-10-21 09:52:13

标签: r cumsum

使用示例描述我想要做的事情可能更容易......说我有以下数据框:

id1 id2 var
1   2   a
2   3   b
2   1   a
3   2   a
2   3   a
4   2   a
3   1   b

您可以按如下方式生成

df <- data.frame(id1 = c(1,2,2,3,2,4,3),
                 id2 = c(2,3,1,2,3,2,1),
                 var = c('a','b','a','a','a','a','b'))

我想要id2在id1中出现的累计次数与同样的var一样,所以我最终会用

id1 id2 var count
1   2   a   0
2   3   b   0 
2   1   a   1
3   2   a   1
2   3   a   1
4   2   a   2
3   1   b   0

因此,第3行中的计数为1,因为我们在第3行(第1行)之前看到id1 = 1和var ='a',然后在第4行中,计数也是1,因为我们看到id1 = 2和var第3行中的“a”(我们只在第4行之前检查,因此不计算我们在第5行中看到的那个)。

如果我检查id1出现在id1中的次数,我会做类似

的事情
with(df, ave(id1 == id1, paste(id1, var), FUN = cumsum))

对于id2,有一种快速简便的方法吗?

提前致谢

2 个答案:

答案 0 :(得分:4)

可能有更优雅的方法,但这可以完成工作。这里的关键是split<-函数。

df$count <- NA # This column must be added prior to calling `split<-`
               # because otherwise we can't assign values to it
split(df, df$var) <- lapply(split(df, df$var), function(x){
    x$count <- cumsum(sapply(1:nrow(x), function(i) x$id2[i] %in% x$id1[1:i]))
    x
})

结果如下。存在一些差异,因此您在手动构建期望结果时遇到了一些错误,或者我误解了这个问题。

  id1 id2 var count
1   1   2   a     0
2   2   3   b     0
3   2   1   a     1
4   3   2   a     2
5   2   3   a     3
6   4   2   a     4
7   3   1   b     0

<强>更新

为了使这个答案完整而有效,这是我对你的解决方案的看法。基本相同,但我认为avelapply更好,更可读。

df$count <- NA
split(df, df$var) <- lapply(split(df, df$var), function(x){
    hit <- sapply(1:nrow(x), function(i) x$id2[i] %in% x$id1[1:i])
    x$count <- ave(hit, x$id2, FUN=cumsum)
    x
})

答案 1 :(得分:1)

使用和编辑了Backlin的答案以获得我想要的,代码如下

df$count<- NA 

split(df, df$var) <- lapply(split(df, df$var), function(x){
    x$count<- sapply(1:nrow(x), function(i) sum(x$id2[i] == x$id1[1:i]))
    x
})

这可能是一种更优雅的方式,但我觉得这很有效......