【问题标题】:R: Cumulatively count number of times column value appears in other columnR:累计计算列值出现在其他列中的次数
【发布时间】:2013-10-21 09:52:13
【问题描述】:

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

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 有没有快速简便的方法?

提前致谢

【问题讨论】:

    标签: r cumsum


    【解决方案1】:

    可能有更优雅的方法可以做到这一点,但这可以完成工作。这里的关键是split&lt;- 函数。

    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
    

    更新:

    只是为了使这个答案完整且有效,这是我对您的解决方案的看法。基本相同,但我认为在lapply 中包含ave 会更好,更易读。

    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
    })
    

    【讨论】:

    • 感谢 Backlin,但这并不能完全满足我的要求,尽管我很害怕。因此,在第 4 行中,您有 count = 2,因为我们之前有两次“点击”,但是对于该行,我只想计算 id2=2 和 var=a 之前出现的次数(在第 3 行中只有一次)
    • 认为我已经通过稍微编辑你的答案来完成我想要做的事情......而不是在第一个 lapply 内做 cumsum,我在使用 df$count
    【解决方案2】:

    已经使用并编辑了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
    })
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      相关资源
      最近更新 更多