Запустите функцию над списком таблиц данных, которая требует ссылки на предыдущую строку. - PullRequest
1 голос
/ 31 мая 2019

Я хотел бы применить функцию ко всем строкам таблицы данных, для всех таблиц данных в списке, однако функция должна ссылаться на предыдущую строку в расчете (кроме строки 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 в NA

1 Ответ

1 голос
/ 31 мая 2019

обновлено, чтобы отразить другие комментарии

для этого случая вы не могли бы просто полностью отказаться от применения функций и сделать что-то вроде:

names(l) <- c("list1","list2")
l <- rbindlist(l,idcol=TRUE)
l[,value := col1 + col2 + col3 * col4,by=.id]
l[,value2 := value / shift(value, fill = 1),by=.id]

, который возвращает

      .id col1 col2 col3 col4 value     value2
 1: list1    2    1    5    1     8  8.0000000
 2: list1    3    2    4    1     9  1.1250000
 3: list1    4    3    3    1    10  1.1111111
 4: list1    2    4    4    1    10  1.0000000
 5: list1    1    3    5    2    14  1.4000000
 6: list2    3    1    5    5    29 29.0000000
 7: list2    4    3    4    5    27  0.9310345
 8: list2    3    4    3    5    22  0.8148148
 9: list2    2    2    2    5    14  0.6363636
10: list2    3    2    3    5    20  1.4285714

важной частью здесь является fill аргумент функции shift(), описанной здесь

...