特别任务中的R语言编程

7

我想了解一下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的显着更改以及文档没有更改,我现在怀疑自己是错误的。有人可以解释吗?

谢谢。


4
不要再做一遍 x <- \[<-`(x, 3:5, 13:15)`,这肯定可以工作。 - Onyambu
3
考虑嵌套子集赋值:x[3:5][2] <- 14 - Roland
@chris。没错,这有点不干净。我希望编译器能够将字符串强制转换为符号。但我只是复制了help.start()中的内容。 - Nicolas2
@Onyambu。抱歉这并没有帮助:我只是复制了文档中的内容。我在想是否有一些地方不是那么明显。 - Nicolas2
它没有 tmp,我刚刚运行了代码而没有使用 tmp - Onyambu
显示剩余7条评论
1个回答

4

首先让我们证明一下文本描述是非常直接的:`*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
+1,解释得很好。但我能说服您使用传统的伪字符串语法,而是对于非语法名称使用正确的反引号引用吗?R文档本身就表示不建议使用字符串引号(即使它自己也不一致地应用该规则)。 - Konrad Rudolph
2
@KonradRudolph,我记得你有为SO使用的语法高亮器做出贡献吗?我真希望它能突出显示\varname`。还有一个错误(将1:103:5`进行比较)。 - Roland
1
@runr 我认为它并不是“隐藏”的:它与常规名称一样处理。在我看来,这是正确的方法。此外,你说你“记得注意到反引号基本上与字符串引号的工作方式相同”,但不幸的是,有令人惊讶的边缘情况,这种情况并不总是成立,这正是我敦促谨慎教授它们的原因:考虑"a" = "b""a" = b。为什么这两个会有不同的结果?在什么情况下,带引号的字符串是名称,何时是值?这非常令人困惑。 - Konrad Rudolph
3
@KonradRudolph \\foo\ 可以翻译成“@KonradRudolph的 `\\`foo\\”。 - Roland
1
@Roland FYI,数字的语法高亮现在已经修复上游。下一个版本还会突出显示运算符和标点符号,所以像\[<-`(`tmp`, …`这样的代码应该更易读(如果Stack Overflow突出显示运算符…)。 - Konrad Rudolph
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接