R 使用:=with eval(as.symbol())创建列

R 使用:=with eval(as.symbol())创建列,r,data.table,R,Data.table,我正在使用R(OS X 10.11.6上的版本3.3.2)中的data.table,并注意到在使用:=操作符和名称字符串方面,从版本1.9.6到1.10.0的行为发生了变化 我正在根据索引号重命名循环中的列。以前,我一直在:=的两侧使用eval(as.symbol(“string”)),但这已经不起作用了(这是基于以前的答案)。通过反复试验,我发现我需要在左侧使用(“string”),在右侧使用eval(as.symbol(“string”) 下面是演示这种行为的MCVE library(dat

我正在使用
R
(OS X 10.11.6上的版本3.3.2)中的
data.table
,并注意到在使用
:=
操作符和名称字符串方面,从版本1.9.6到1.10.0的行为发生了变化

我正在根据索引号重命名循环中的列。以前,我一直在
:=
的两侧使用
eval(as.symbol(“string”))
,但这已经不起作用了(这是基于以前的答案)。通过反复试验,我发现我需要在左侧使用
(“string”)
,在右侧使用
eval(as.symbol(“string”)

下面是演示这种行为的MCVE

library(data.table)
dt <- data.table(col1 = 1:10, col2 = 11:20)

## the next lines would be inside a loop that is excluded to simplify this MCVE
colA = paste0("col", 1)
colB = paste0("col", 2)
colC = paste0("col", 3)

## Old code that worked with 1.9.6, but not longer works
dt[ , eval(as.symbol(colC)) := eval(as.symbol(colA)) + eval(as.symbol(colB))]

## New code that now works 1.10.0
dt[ , (colC) := eval(as.symbol(colA)) + eval(as.symbol(colB))]
库(data.table)
dt从a开始,现在假设如果
j
是一个字符串,它将作为一个符号进行计算,因此,例如,
dt[,“col”:=3]
也将起作用

这一默认设置的确切时间有相当大的变化,但完整的故事都包含在上一篇文章和
data.table

但是,您可能会感兴趣

new_cols = c("j1", "j2")
dt[, (new_cols) := value]  # brackets so we don't just make a new_col col

您可以在不需要循环的情况下实现上述功能

library(data.table)

dt = data.table(a = c(2, 3), b = c(5, 7), c = c(11, 13))

cols1 = sapply(c("a", "b"), as.symbol)
cols2 = sapply(c("b", "c"), as.symbol)
new_cols = c("d", "e")

> print(dt)
   a b  c
1: 2 5 11
2: 3 7 13

dt[, (new_cols) := purrr::map2(cols1, cols2, ~ eval(.x) + eval(.y))]

   a b  c  d  e
1: 2 5 11  7 16
2: 3 7 13 10 20
从a开始,现在假设如果
j
是单个字符串,则将其作为符号进行计算,因此,例如,
dt[,“col”:=3]
也将起作用

这一默认设置的确切时间有相当大的变化,但完整的故事都包含在上一篇文章和
data.table

但是,您可能会感兴趣

new_cols = c("j1", "j2")
dt[, (new_cols) := value]  # brackets so we don't just make a new_col col

您可以在不需要循环的情况下实现上述功能

library(data.table)

dt = data.table(a = c(2, 3), b = c(5, 7), c = c(11, 13))

cols1 = sapply(c("a", "b"), as.symbol)
cols2 = sapply(c("b", "c"), as.symbol)
new_cols = c("d", "e")

> print(dt)
   a b  c
1: 2 5 11
2: 3 7 13

dt[, (new_cols) := purrr::map2(cols1, cols2, ~ eval(.x) + eval(.y))]

   a b  c  d  e
1: 2 5 11  7 16
2: 3 7 13 10 20

常见问题解答被视为文档的一部分和必要的阅读材料。这里的一般建议(问题1.6)似乎是建立一个单一的表达式和评估:
e=substitute(colC:=ColA+ColB,list(ColA=as.symbol(“col1”)、ColB=as.symbol(“col2”)、colC=as.symbol(“col3”);dt[,eval(e)]
。我不知道为什么你的代码以前可以工作,但现在不行了。@Frank谢谢。我以前看过FAQ,但以前没有注意到这一部分。另外,这个指针帮助我知道将来要搜索什么。FAQ被认为是文档和必要阅读的一部分。这里的一般建议(问题1.6)似乎是建立一个单一的表达式和评估:
e=substitute(colC:=ColA+ColB,list(ColA=as.symbol(“col1”)、ColB=as.symbol(“col2”)、colC=as.symbol(“col3”);dt[,eval(e)]
。我不知道为什么你的代码以前可以工作,但现在不行了。@Frank谢谢。我以前看过FAQ,但以前没有注意到这一部分。另外,这个指针帮助我知道将来要搜索什么。仅供参考,您可以进一步简化,
“col1”:=
col1:=
(c(“j1”,“j2”):=
c(“j1”,“j2”):=
,并且您给出的所有示例都是从该软件包的早期版本开始的。您的示例不包括“if
j
是单个字符串”的情况。。。Fwiw,该案例在1.9.8中进行了更改,在变更日志的第3项中进行了描述:但在这里似乎不相关。我知道后者以前是可用的,但我想指出的是,随着新语法OP的采用,可以添加多个列,以防对他们有利。在第一个例子中,我不知道这以前是可能的。我是否错误地归因于错误?是的,我不确定OP的代码停止工作的确切原因,但我认为这与新的“if
j
是单个字符串”行为无关。不过,我可能错了。顺便说一句,我认为保留您删除的
c(“j1”、“j2”):=
很好。我一直都是这样做的。仅供参考,您可以进一步简化,
“col1”:=
col1:=
(c(“j1”、“j2”):=
c(“j1”、“j2”):=
,并且您给出的所有示例都是从该软件包的早期版本开始的。您的示例不包括“if
j
是单个字符串”的情况。。。Fwiw,该案例在1.9.8中进行了更改,在变更日志的第3项中进行了描述:但在这里似乎不相关。我知道后者以前是可用的,但我想指出的是,随着新语法OP的采用,可以添加多个列,以防对他们有利。在第一个例子中,我不知道这以前是可能的。我是否错误地归因于错误?是的,我不确定OP的代码停止工作的确切原因,但我认为这与新的“if
j
是单个字符串”行为无关。不过,我可能错了。顺便说一句,我认为保留您删除的
c(“j1”、“j2”):=
很好。我一直都是这样做的。