【问题标题】:Why does the := operator behave differently with different constructions?为什么 := 运算符在不同的结构中表现不同?
【发布时间】:2019-12-02 04:27:30
【问题描述】:

我正在尝试在 r 中使用 := 运算符来分配我在函数中提供的名称的变量。
为了在分配多个变量时保持代码可读性,我想使用 :=(paste0("var",i)=3) 构造。但它的行为似乎与 paste0("var",i):=3 构造不同。

这是 := 的预期行为还是我遗漏了什么? 我可以做些什么来使:= 构造工作吗?

例子:

dt<-data.table(var1=1:10)
#This works fine:
dt[,paste0("var",1):=3]
#But this throws an error:
dt[,`:=`(paste0("var",1)=3)]
Error: unexpected '=' in "dt[,`:=`(paste0("var",1)="

【问题讨论】:

  • 你在寻找dt[,:=(paste0("var",1), 3)]
  • 哇!这样可行!谢谢!现在我特别困惑!它在做什么?多个变量的语法是什么?
  • 你可以看到help(":=")并通过egs工作

标签: r syntax data.table operator-keyword


【解决方案1】:

这不是一个真正的data.table 问题,而是一个 R 问题:

list(paste0('var', 1) = 3)

错误:“list(paste0('var', 1) ="

中出现意外的 '='

要构造这样的名称,请使用:= 作为中缀运算符:

dt[ , paste0('var', 1) := 3]

【讨论】:

  • 交替且可读性较差的dt[,`:=`(paste0("var",1), 3)] 可以使用任何中缀运算符,例如`+`(1,2)
【解决方案2】:

我认为有 3 种方式来看待这个问题。前两种方式来自help(":=")

1) LHS := RHS 形式

# DT[i, LHS := RHS, by = \dots]
# DT[i, c("LHS1", "LHS2") := list(RHS1, RHS2), by = \dots]

2) 函数形式

# DT[i, `:=`(LHS1 = RHS1,
#            LHS2 = RHS2,
#            \dots), by = \dots]

这里LHS 可以是一个对字符向量求值的东西,但LHS1LHS2 已经是单长字符了。

3) 第三种方法是将:= 视为二元运算符函数,因此dt[,:=(paste0("var",1), 3)] 也可以工作。

在 R 中,您不能使用要动态评估的参数名称调用函数(无需深入研究非标准评估)。例如,

f <- function(x1) x1
f(paste0("x", 1)=3)

错误:" f(paste0("x", 1)="

中出现意外的 '='

解决 OP 的 cmets 的示例:

dt[, c(paste0("var", 1), "var2") := .(1, 2)]

dt[, `:=`(var3=3, var4=4)]

val <- c(var5=5, var6=6)
for (x in paste0("var", 5:6))
    set(dt, j=x, value=val[x])

【讨论】:

  • 谢谢。总体而言,我希望使用的代码结构似乎不起作用。所以我会走另一条路。我想我可以通过链接获得足够的距离,例如:dt[,paste0("var",1):=1][,paste0("var",2):="Hello"] 等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
  • 1970-01-01
相关资源
最近更新 更多