【问题标题】:Special assignment in RR中的特殊任务
【发布时间】:2021-05-12 18:03:10
【问题描述】:

我的问题只是了解 R 语言的一个特性是如何工作的。在 R 的任何良好版本附带的“R 语言定义”中,都有一些解释,例如,向量元素的设置如何与看起来像赋值但并不那么简单的东西一起工作:

x[3:5] <- 13:15

是一个快捷方式:

`*tmp*` <- x
x <- "[<-"(`*tmp*`, 3:5, value=13:15)
rm(`*tmp*`)

我不明白的是为什么使用中间符号 *tmp* 而不是直接用 setter 函数做事情。

x <- "[<-"(x, 3:5, value=13:15)

直到现在我都怀疑它与垃圾收集有关,但由于这个在 v4 中发生了显着变化,而且文档没有改变,我现在怀疑我错了。谁能解释一下?

谢谢

【问题讨论】:

  • 不要再这样做了x &lt;- `[&lt;-`(x, 3:5, 13:15) 肯定可以工作
  • 考虑嵌套子集赋值:x[3:5][2]
  • 如果使用" 代替`,可能会混淆编译器。
  • @chris。对,有点脏。我希望编译器能够将字符串强制转换为符号。但我只是复制了 help.start() 中的内容。
  • @Onyambu。抱歉,它没有帮助:我只是复制了文档中的内容。我想知道是否有不那么明显的地方。

标签: r


【解决方案1】:

好的,首先让我们证明描述是相当字面的:`*tmp*` 是实际创建的。

`*tmp*` <- NULL
lockBinding("*tmp*", .GlobalEnv)
x[3:5] <- 13:15
#Error: cannot change value of locked binding for '*tmp*'
unlockBinding("*tmp*", .GlobalEnv)

现在,语言定义解释了该机制非常通用,也用于更复杂的分配。下面是一个示例,如果您不使用 `*tmp*` 对象,它实际上会产生不同的结果:

x <- 1:10
local({
  x <- 11:20
  x[3:5] <<- 13:15
})
x
#[1]  1  2 13 14 15  6  7  8  9 10

x <- 1:10
local({
  x <- 11:20
  x <<- `[<-`(x, 3:5, value=13:15)
})
x
# [1] 11 12 13 14 15 16 17 18 19 20

x <- 1:10
local({
  x <- 11:20
  `*tmp*` <- get("x", envir=parent.env(environment()), inherits=TRUE)
  x <<- `[<-`(`*tmp*`, 3:5, value=13:15)
  rm(`*tmp*`)
})
x
# [1]  1  2 13 14 15  6  7  8  9 10

可能还可以找到其他示例。

【讨论】:

  • +1,很好的解释。但是我能否说服您not 使用传统的伪字符串语法,而是对非语法名称使用正确的反引号? R 文档本身说不鼓励使用字符串引号(即使它本身不一致地应用)。
  • @KonradRudolph 我是否记得您为 SO 使用的语法高亮器做出了贡献?我真的希望它能突出显示`varname`。似乎还有一个错误(比较 1:103:5)。
  • @runr 我不认为它是“隐藏的”:它被视为与常规名称相同。恕我直言,这是正确的方法。此外,您说您“记得注意到反引号的工作方式与字符串引号基本相同”,不幸的是,在一些令人惊讶的极端情况下这是不正确的,这正是我在教他们时要小心的原因:考虑 "a" = "b""a" = b。为什么这两个做不同的事情?在什么情况下,带引号的字符串是名称,什么时候是值?这令人难以置信的混乱。
  • @KonradRudolph \`foo\`
  • @Roland 仅供参考,数字的语法高亮现在是fixed upstream。下一个版本还会突出显示运算符和标点符号,因此 `[&lt;-`(`*tmp*`, … 等代码应该更具可读性(如果 Stack Overflow 突出显示运算符……)。
猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
相关资源
最近更新 更多