我有一个data.table,如下所示:
Sim j active cost
1: 1 1 1 100
2: 1 2 1 125
3: 1 3 0 200
4: 1 4 1 250
5: 2 1 1 100
6: 2 2 0 50
7: 2 3 0 125
8: 2 4 1 200
dt <- data.table(Sim = c(1, 1, 1, 1, 2, 2, 2, 2),
j = c(1, 2, 3, 4, 1, 2, 3, 4),
active = c(1, 1, 0, 1, 1, 0, 0, 1),
cost = c(100, 125, 200, 250, 100, 50, 125, 200))
Run Code Online (Sandbox Code Playgroud)
我想添加一个列'incr_cost',它从不同行中的成本中减去每行i中的成本,我将其称为行k,其中行k满足以下条件:
对于j = 1的行,incr_cost可以只是NA.
在我的示例中,解决方案看起来像:
Sim j active cost incr_cost
1: 1 1 1 100 NA
2: 1 2 1 125 25
3: 1 3 0 200 75
4: 1 4 1 250 125
5: 2 1 1 100 NA
6: 2 2 0 50 -50
7: 2 3 0 125 25
8: 2 4 1 200 100
Run Code Online (Sandbox Code Playgroud)
看起来这类似于shift的应用程序,除了不是按原样"移位"data.table,我想转移行减少的data.table,其中不符合我的条件的行被过滤掉.我很难理解如何识别具有小于当前行的最大j值的行(并且满足其他两个条件).
以下工作除了在选择行k时不考虑行是否处于活动状态:
dt[, incr_cost := cost - shift(cost, fill=NA), by=Sim]
Run Code Online (Sandbox Code Playgroud)
我正在使用r data.table,但也欢迎非data.table解决方案.谢谢!
您可以使用滚动连接:
dt[, v :=
cost - .SD[.(active = 1, Sim = Sim, j = j - 1), on=.(active, Sim, j), roll=TRUE, x.cost]]
Sim j active cost v
1: 1 1 1 100 NA
2: 1 2 1 125 25
3: 1 3 0 200 75
4: 1 4 1 250 125
5: 2 1 1 100 NA
6: 2 2 0 50 -50
7: 2 3 0 125 25
8: 2 4 1 200 100
Run Code Online (Sandbox Code Playgroud)
这会查找元组.(active = 1, Sim = Sim, j = j - 1),当找不到完全匹配时,"滚动"到最后一个j适合的值,如果有的话.
这个怎么运作
在j的x[i, j],.SD只是对表本身的简写,"数据的子集".
在j加入x[i, on=, roll=, j]......
x.*是指x(here,.SD)的列; 和类似的i.*将是i(这里,元组)的列的前缀.(OP的使用j可能会让人感到困惑.我的意思是j,这个论点在DT[i, j, ...].)
| 归档时间: |
|
| 查看次数: |
367 次 |
| 最近记录: |