EdM*_*EdM 7 r data-manipulation dplyr data.table
好的,这是我希望使用高效,优雅的解决方案解决的问题,例如data.table或dplyr.
限定:
DT = data.table(group=c(rep("A",3),rep("B",5)),value=c(2,9,2,3,4,1,0,3))
time group value
1: 1 A 2
2: 2 A 9
3: 3 A 2
4: 1 B 3
5: 2 B 4
6: 3 B 1
7: 4 B 0
8: 5 B 3
Run Code Online (Sandbox Code Playgroud)
我想要得到的是一组累计和的值除以它们被观察的时刻的逆序.
time group value RESULT
1: 1 A 2 2.000000
2: 2 A 9 10.000000
3: 3 A 2 7.166667
4: 1 B 3 3.000000
5: 2 B 4 5.500000
6: 3 B 1 4.000000
7: 4 B 0 2.583333
8: 5 B 3 4.933333
Run Code Online (Sandbox Code Playgroud)
在第5行,结果是:
4/1 + 3/2 = 5.5
因为在时间2,B组有2个观察值,最后一个除以1,前一个除以1.接着第6行结果是:
1/1 + 4/2+ 3/3 = 4
因为在时间3,B组有3个观察值,最后一个除以1,前一个除以2,前一个除以3.在第7行0/1 + 1/2 + 4/3 + 3/4 = 2.583333,依此类推......
数据很大,所以避免循环是必不可少的!
我用矩阵代数:
n_max = DT[, .N, by=group][, max(N)]
m = matrix(0, n_max, n_max)
m[] = ifelse( col(m) >= row(m), 1 / (col(m) - row(m) + 1 ), m)
DT[, res := value %*% m[seq_len(.N), seq_len(.N)], by=group ]
group value res
1: A 2 2.000000
2: A 9 10.000000
3: A 2 7.166667
4: B 3 3.000000
5: B 4 5.500000
6: B 1 4.000000
7: B 0 2.583333
8: B 3 4.933333
Run Code Online (Sandbox Code Playgroud)