【问题标题】:Unable to use eval(parse(...)) in data.table [,:=] function无法在 data.table [,:=] 函数中使用 eval(parse(...))
【发布时间】:2014-03-13 10:17:59
【问题描述】:

我不确定我是否在这里犯了错误(使用eval(parse(...)) 的危险),但在这里我尝试在更新data.table 列时使用eval(parse(...)),这会产生错误。下面是我的代码。

require(data.table)
# Loading required package: data.table
# data.table 1.9.2  For help type: help("data.table")
DT<-data.table(x=seq(1,10,1),
               y=seq(2,20,2))
DT[,y:=y*eval(parse(text="1*2"))] #Doesn't work
# Error in y * expression(1 * 2) : non-numeric argument to binary operator
variable <- eval(parse(text="1*2"))
DT[,y:=y*variable] #Works
DT
#     x  y
# 1:  1  4
# 2:  2  8
# 3:  3 12
# 4:  4 16
# 5:  5 20
# 6:  6 24
# 7:  7 28
# 8:  8 32
# 9:  9 36
#10: 10 40

【问题讨论】:

标签: r data.table


【解决方案1】:

这种行为,bug #5423,现在在 data.table v1.9.3 的当前开发版本的提交 #1234 中得到修复。来自NEWS

o DT[,y := y * eval(parse(text="1*2"))] 导致错误,除非 eval() 用括号括起来。即DT[,y := y * (eval(parse(text="1*2")))]。现在已修复,关闭 #5423。感谢 Wet Feet 的报告和 Simon O'Hanlon 发现问题here on SO


无论您为什么要这样做以及相对优点与否,这都是关于优先顺序的。您需要将整个 eval(parse(text="1*2")) 包裹在一组括号中,以确保在您尝试将其乘以 y...

之前对其进行评估
DT[,y:=y*(eval(parse(text="1*2")))] 
#     x  y
# 1:  1  4
# 2:  2  8
# 3:  3 12
# 4:  4 16
# 5:  5 20
# 6:  6 24
# 7:  7 28
# 8:  8 32
# 9:  9 36
#10: 10 40

不带括号的data.table::":=" 试图将yexpression 对象相乘,这将导致语法错误。

【讨论】:

  • 谢谢,实际上这样做的原因是允许用户在脚本中键入分数。创建一个额外的变量只是为了这样做(在循环中)似乎非常浪费!
  • R 评估 10 * eval(parse(text="1*2")) 没有任何额外的括号很好 - 这是特定于数据表的东西。
  • @hadley 很好,但解决方案仍然正确(所以我不同意你的反对意见),我仍然认为它不起作用的原因仍然是因为*由于未评估 eval 而看到一个表达式对象。我会把R改成data.table::":="
猜你喜欢
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2013-04-01
相关资源
最近更新 更多