2

使用示例来描述我想要做什么可能更容易......假设我有以下数据框:

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 'a'在第 3 行(我们只在第 4 行之前检查,所以不要计算我们在第 5 行看到的那个)。

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

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

有没有一种快速简便的方法来为 id2 执行此操作?

提前致谢

4

2 回答 2

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
})
于 2013-10-21T10:18:13.337 回答
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
})

可能有一种更优雅的方法,但我认为这很有效......

于 2013-10-21T10:44:03.577 回答