【发布时间】:2017-03-01 16:52:28
【问题描述】:
这类似于Update values in data.table with values from another data.table 和R data.table replacing an index of values from another data.table,除了在我的情况下变量的数量非常大,所以我不想明确列出它们。
我拥有的是一个大的data.table(我们称之为dt_original)和一个较小的data.table(我们称之为dt_newdata),它们的ID是第一个的子集,它只有一些变量第一个。我想用dt_newdata 中的值更新dt_original 中的值。为了增加一个转折点,我仅想有条件地更新这些值 - 在这种情况下,仅当 dt_newdata 中的值大于 dt_original 中的相应值时。
对于可重现的示例,以下是数据。在现实世界中,表格要大得多:
library(data.table)
set.seed(0)
## This data.table with 20 rows and many variables is the existing data set
dt_original <- data.table(id = 1:20)
setkey(dt_original, id)
for(i in 2015:2017) {
varA <- paste0('varA_', i)
varB <- paste0('varB_', i)
varC <- paste0('varC_', i)
dt_original[, (varA) := rnorm(20)]
dt_original[, (varB) := rnorm(20)]
dt_original[, (varC) := rnorm(20)]
}
## This table with a strict subset of IDs from dt_original and only a part of
## the variables is our potential replacement data
dt_newdata <- data.table(id = sample(1:20, 3))
setkey(dt_newdata, id)
newdata_vars <- sample(names(dt_original)[-1], 4)
for(var in newdata_vars) {
dt_newdata[, (var) := rnorm(3)]
}
这是一种使用循环和pmax 的方法,但必须有更好的方法,对吧?
for(var in newdata_vars) {
k <- pmax(dt_newdata[, (var), with = FALSE], dt_original[id %in% dt_newdata$id, (var), with = FALSE])
dt_original[id %in% dt_newdata$id, (var) := k, with = FALSE]
}
似乎应该有一种使用连接语法的方法,可能是前缀i. 和/或.SD 或类似的东西,但我尝试过的任何方法都不足以保证在这里重复。
【问题讨论】:
-
是的,您的 pmax 看起来很像
dt_original[dt_newdata, on=.(id), pmax(x.varB, i.varB)],唯一的问题是坚持将“varB”作为字符传递...可能可以通过将数据放入长格式而不是宽格式来解决。 -
请使用
set.seed使此可重现 -
已添加
set.seed(0),谢谢。 -
将
varB视为数百个变量名称的异构混合,它是dt_original中变量的任意子集。这个例子可能会让它看起来有点太规则了。 -
名称是否异类无关紧要。它们显然都是数字的(根据您对 pmax 的使用判断),这意味着它们可以在长格式数据集中的单个列中很好地协同工作。那是
melt(dt_original, id="id")。从那里,您可能还希望将 var 名称拆分为组件部分......(变量和年份)。如果您对此感兴趣,我建议您查看 Hadley 的文章:jstatsoft.org/article/view/v059i10
标签: r data.table