И снова итерация строк по таблице данных - PullRequest
0 голосов
/ 26 апреля 2018

Есть, по крайней мере, пара вопросов и ответов, которые похожи на это, но я не могу понять, как это работает.Вот воспроизводимый пример.DT хранит данные.Я хочу, чтобы еда (n) = еда (n-1) * xRatio.food (n)

DT <- fread("year    c_Crust xRatio.c_Crust
X2005 0.01504110             NA
X2010         NA      0.9883415
X2015         NA      1.0685221
X2020         NA      1.0664189
X2025         NA      1.0348418
X2030         NA      1.0370386
X2035         NA      1.0333771
X2040         NA      1.0165511
X2045         NA      1.0010563
X2050         NA      1.0056368")

Код, который ближе всего подходит к формуле:

DT[,res := food[1] * cumprod(xRatio.food[-1])]

, но кодзначение сдвигается вверх, и первое значение возвращается в последнюю строку с предупреждением.Я хочу, чтобы первое значение xRatio.food было NA

1 Ответ

0 голосов
/ 26 апреля 2018

Я бы переименовал / изменил форму ...

myDT = melt(DT, id = "year", meas=list(2,3), 
  variable.name = "food", 
  value.name = c("value", "xRatio"))[, food := "c_Crust"][]

# or for this example with only one food...
myDT = DT[, .(year, food = "c_Crust", xRatio = xRatio.c_Crust, value = c_Crust)]

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

myDT[, v := replace(first(value)*cumprod(replace(xRatio, 1, 1)), 1, NA), by=food]

# or more readably, to me anyways
library(magrittr)
myDT[, v := first(value)*cumprod(xRatio %>% replace(1, 1)) %>% replace(1, NA), by=food]

Альтернативно, естьmyDT[, v := c(NA, first(value)*cumprod(xRatio[-1])), by=food], расширяя код OP, хотя я предпочитаю просто работать с полноразмерными векторами с заменой, а не пытаться строить векторы с c, так как последний может столкнуться со странными крайними случаями (например, если есть только одна строка,это будет делать правильно?).

...