【问题标题】:r rowdies iteration on a data table, again再次在数据表上进行 r rowdies 迭代
【发布时间】:2018-10-06 13:16:45
【问题描述】:

至少有几个与此类似的 Q/A,但我似乎无法掌握它。这是一个可重现的示例。 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])]

但是 res 值上移了,第一个值被回收到最后一行并带有警告。我希望 xRatio.food 的第一个值为 NA

【问题讨论】:

  • 我猜是 DT[, v := first(c_Crust)*cumprod(replace(xRatio.c_Crust, 1, 1))*NA^(.I==1)] 但不知道,因为我没有看到想要的输出。
  • 我一直在学习.... 你能解释一下replace(xRatio.c_Crust, 1, 1) 的组合吗,我解释为将 xRatio.c_Crust 的第一个值替换为 1 和乘法 *NA^(.I==1) ?我特别不明白最后一个词。
  • 你的解释是对的。 NA^cond 是在我看到您希望第一个值为 NA 时添加的 hack。当 cond 为 FALSE/TRUE 时,它是 1/NA... 一个更易读的解决方案是将整个内容包装在 replace(other_code, 1, NA) 而不是 other_code*NA^(.I==1) 中。无论如何,假设结果是正确/预期的,我将转换为答案

标签: r data.table iteration


【解决方案1】:

我会重命名/重塑...

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 构建向量,因为后者可能会遇到奇怪的边缘情况(比如 if只有一行,它会做正确的事吗?)。

【讨论】:

    猜你喜欢
    • 2013-07-01
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2016-08-12
    相关资源
    最近更新 更多