【问题标题】:How to add/change multiple data.table columns with variable expressions如何使用变量表达式添加/更改多个 data.table 列
【发布时间】:2014-06-10 19:41:23
【问题描述】:

我在 data.tables 和其他一些 data.tables 中有多个海量数据集,其中包含我想使用 := 之类的东西对它们执行的基本表达式列表。

样本数据:

library(data.table)
tt = data.table(date=c(2011, 2012, 2013, 2014), count=c(2774343,4655434,648113695, 357733805))

   date     count
1: 2011   2774343
2: 2012   4655434
3: 2013 648113695
4: 2014 357733805

示例转换表。一些列可能是新列,其他列可能正在修改预先存在的列。我需要他们充分利用“with”功能,这意味着他们需要引用现有列,即使他们正在创建新列。

xform=data.table(var=c("date2", "count2"), val=c("date - 2000", "count / 1000"))

      var          val
1:  date2  date - 2000
2: count2 count / 1000

我只是无法想象让它发挥作用所需的神奇公式。我在 [.data.table 中使用 := 尝试了 lapply、parse、eval 等的各种组合。

我最后的希望是这样的:

> xform[,expr := lapply(val, FUN=function(x) parse(text=x))]
> tt[,(xform$var) := eval(xform$expr)]
Error in eval(expr, envir, enclos) : attempt to apply non-function

诀窍是我的输入数据非常庞大,最多包含 100 列,虽然有些转换可能很简单,但其他转换可能很复杂。

在这种情况下,输出应该是这样的:

   date     count date2     count2
1: 2011   2774343    11   2774.343
2: 2012   4655434    12   4655.434
3: 2013 648113695    13 648113.695
4: 2014 357733805    14 357733.805

提前感谢您的帮助!

【问题讨论】:

  • 我只设法让它与一个表达式一起工作,例如,xform=data.table(var="date2", val="date - 2000"); tt[,xform$var := eval(parse(text = xform$val))]
  • 我也试过了!由于 parse 无法列出列表,因此我分别尝试了 lapply(val,parse) 和 eval 阶段;我想我可能会碰到[.data.table:= 的一些内部逻辑,但我无法想象是什么。

标签: r data.table


【解决方案1】:

我认为您必须逐行执行此操作(xform):

for(i in 1:nrow(xform))
  tt[, xform$var[i] := eval(parse(text = xform$val[i]))]

tt
#   date     count date2     count2
#1: 2011   2774343    11   2774.343
#2: 2012   4655434    12   4655.434
#3: 2013 648113695    13 648113.695
#4: 2014 357733805    14 357733.805

如果您将转换存储为函数而不是文本,则可以改为执行以下操作:

xform = data.table(var = c("date2", "count2"),
                   val = c(quote(date - 2000), quote(count / 1000)))

tt[, xform$var := lapply(xform$val, eval, .SD)]

【讨论】:

  • 是的,我打算根据我在评论中的发现提出建议,但我认为你和@Arun 会嘲笑我 :)
  • @DavidArenburg 很公平 - 添加了另一个选项 :)
  • (+1) 太棒了。我认为您应该删除循环一,然后留下第二个解决方案。我喜欢你把.SD放在最后并在xform$val上操作的方式,我永远不会想出那个
  • 好的,看起来我很接近了:只需使用 xform[,expr := lapply(val, FUN=function(x) parse(text=x))] 解析转换,然后使用 tt[,xform$var := lapply(xform$expr, eval, .SD)] 评估它们 .SD 的魔力是什么,因为没有 @987654330 @ 或 keyby?
  • @Grisby_2133 请参阅this post 了解.SD 的魔力
猜你喜欢
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 2014-10-16
  • 2015-07-15
相关资源
最近更新 更多