在数据表列表上应用函数,该函数需要引用上一行

时间:2019-05-31 14:03:15

标签: r data.table apply

对于列表中的所有数据表,我想对数据表的所有行应用一个函数,但是该函数必须引用计算中的前一行(除了独立的第1行之外)

我可以在不需要参考上一行时做到这一点;

require(data.table)

# dummy list data
l <- list(data.table(col1=c(2,3,4,2,1), col2=c(1,2,3,4,3), col3=c(5,4,3,4,5), col4=c(1,1,1,1,2)), data.table(col1=c(3,4,3,2,3), col2=c(1,3,4,2,2), col3=c(5,4,3,2,3), col4=c(5,5,5,5,5)))

# apply the function to the data table by row, and apply this function to all tables in the list
lapply(l, function(b) b[ , value := mapply(function(w,x,y,z) w + x + y * z, col1, col2, col3, col4)])

但是我如何使value考虑到上一行的value

# this wont work b'cos value hasn't been created yet
lapply(l, function(b) b[ , value := mapply(function(w,x,y,z) w + x + y * z, col1, col2, col3, col4)])

 Error in mapply(function(w, x, y, z, v) (w + x + y * z)/shift(v, 1), col1,  : 
  object 'value' not found 

# so make 'value' for row 1 only and try again
lapply(l, function(b) b[ , value := 0])
lapply(l, function(b) b[1 , value := col1 + col2 + col3 - col4])

# using shift inside mapply
lapply(l, function(b) b[ , value := mapply(function(w,x,y,z,v) (w + x + y * z) / shift(v,1), col1, col2, col3, col4, value)])

value列全部转换为NAs

1 个答案:

答案 0 :(得分:1)

尽管不清楚您要的是什么,但似乎您想保留value的第一行,然后再将value的每一行除以前一行。

在这种情况下,您不能完全避免内部mapply并执行矢量化的操作,例如:

    lapply(l, function(b){
              b[,value := col1 + col2 + col3 * col4]
              b[,value2 := value / shift(value,fill=1)]
                         })

返回

[[1]]
   col1 col2 col3 col4 value   value2
1:    2    1    5    1     8 8.000000
2:    3    2    4    1     9 1.125000
3:    4    3    3    1    10 1.111111
4:    2    4    4    1    10 1.000000
5:    1    3    5    2    14 1.400000

[[2]]
   col1 col2 col3 col4 value     value2
1:    3    1    5    5    29 29.0000000
2:    4    3    4    5    27  0.9310345
3:    3    4    3    5    22  0.8148148
4:    2    2    2    5    14  0.6363636
5:    3    2    3    5    20  1.4285714

这里的重要部分是fill命令described here

shift()自变量