首页 > 解决方案 > 使用 R 的列的累积计数

问题描述

我有这样的数据

structure(list(id = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2), drug_1 = c(0, 
0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1), drug_2 = c(0, 1, 1, 1, 1, 0, 
1, 0, 0, 1, 0, 1)), class = "data.frame", row.names = c(NA, -12L
))

我想获取每个 id 的每一列的累积计数并获取这样的数据

structure(list(id2 = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2), drug_1_b = c(0, 
0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 2), drug_2_b = c(0, 1, 2, 3, 4, 
0, 5, 0, 0, 1, 0, 2)), class = "data.frame", row.names = c(NA, 
-12L))

标签: r

解决方案


您可以使用 获得累积总和cumsum

要将 data.frame 拆分为子集,您可以使用split然后 lapplycumsum在 data.frames 列表上并再次在列列表上,或者您可以使用ave完全执行此操作的函数:

data = structure(list(id = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2), drug_1 = c(0, 
0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1), drug_2 = c(0, 1, 1, 1, 1, 0, 
1, 0, 0, 1, 0, 1)), class = "data.frame", row.names = c(NA, -12L
))
data[-1] = ave(data[-1], data$id, FUN=cumsum)

编辑:我假设要求累积总和(根据说明)并且示例数据中存在错误。如果示例数据正确,则条件是如果计数为零,则不要进行累积求和并保持为零ifelse(x == 0, 0, cumsum(x))(根据@r2evans)。但是,此构造在应用于 data.frame 时不起作用。需要一个更复杂的辅助函数:

data[-1] = ave(data[-1], data$id, FUN=function(x){
    y = cumsum(x)
    y[x == 0] = 0
    y
    })

我们现在可以将其与请求的(重命名的)数据进行比较:

result = structure(list(id = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2), drug_1 = c(0, 
0, 0, 0, 0, 1, 2, 0, 0, 1, 0, 2), drug_2 = c(0, 1, 2, 3, 4, 
0, 5, 0, 0, 1, 0, 2)), class = "data.frame", row.names = c(NA, 
-12L))
identical(data, result)

推荐阅读