【发布时间】:2018-10-09 12:19:56
【问题描述】:
我有一个包含 2x 数据列和两个 id 列的数据表。 id 列是带有值(X2010、X2015、X2020 等)和国家(cty1、cty2 等)的年份。对于每个国家/地区,第一组数据列(f1、f2、f3 等)仅在第一行 (X2010) 中具有值,在其余行中具有 NA。第二组列(x.f1、x.f2、x.f3 等)在第一行中具有 NA,而在其余行中具有不同的值。我想将第一组列中的 NA 替换为每个国家/地区的以下递归结构。
f1.X2015 = f1.X2010 * x.f1.X2015
f1.X2020 = f1.X2015 * x.f1.X2020
...
我已经尝试了以下
foods <- c("f1", "f2", "f3")
x.foods <- c("x.f1", "x.f"2, "x.f3")
res <- c("res.f1", "res.f2", "res.f3")
f.cumprod <- function(x,y) {return(first(x) * cumprod(replace(y), 1,1) * NA^(.I= 1))}
这是我认为可以为 res 列生成值的数据表结构。
DT[,(res) := mapply(FUN = f.cumprod, x = .SD, y = list(x.foods)), .SDcols = foods, by = c("cty")]
这是一个仅适用于一个国家/地区的简化版本
set.seed(24)
dt <- data.table(cty = c(rep("cty1", 5), rep("cty2", 5), rep("cty3", 5)), year = rep(c("X2010", "X2015", "X2020", "X2025", "X2030"), 3),
f1 = rep(c(0.9883415, rep(NA, 4)), 3), f2 = rep(c(1.0685221, rep(NA, 4)), 3), f3 = rep(c(1.0664189, rep(NA, 4)), 3),
x.f1 = rep(c(NA, rep(rnorm(4))), 3), x.f2 = rep(c(NA, rep(rnorm(4))), 3), x.f3 = rep(c(NA, rep(rnorm(4))), 3))
还有一种笨拙而缓慢的方式来获得其中一种食物的结果,f1。
dt.subset <- dt[, c("f1", "x.f1"), with = FALSE]
for (i in 2:nrow(dt.subset)) {
dt.subset$f1[i] <- dt.subset$f1[i - 1] * dt.subset$x.f1[i]
}
由于我想为大约 170 个国家和 20 种食品(以及 4 个场景)执行此操作,我希望有一个类似于上述 DT 代码的解决方案。
【问题讨论】:
-
你想申请哪一个。它是第二个功能还是第一个。顺便说一句,您的示例中有一些错字
-
我想使用 f.cumprod 或它的某个版本(这是你在另一篇文章中给我的)。如果我了解 cumprod 的工作原理,for 循环给出的结果与 f.cumprod 函数针对单个国家和食物的结果相同。我是否理解您关于哪个功能正确的问题?
-
您的函数似乎有拼写错误,即
.I=1。是.I==1吗?最好有一个使用mapply的示例数据,因为"cty"不在dt中 -
除此之外不清楚
replace在做什么cumprod(replace(y), 1,1)这里,我认为是括号不匹配 -
有一个错字。应该是
.I==1。 replace xxx 结构来自@Frank 在stackoverflow.com/questions/50032823/… 的评论中的一些代码。
标签: r data.table