我建议使用类似for( i in 1:10 ) z[,i] <- N[,i]
...
但是,既然你说你想学习新东西,你可以玩弄parse
and substitute
。
注意:这些小工具很有趣,但有经验的用户(不是我)避免使用它们。
这被称为“语言计算”。这很有趣,它有助于理解 R 的工作方式。让我试着做一个介绍:
基本的语言结构是一个常数,如数字或字符向量。它是微不足道的,因为它与其“未评估”版本没有什么不同,但它是更复杂表达式的构建块之一。
(官方)基本语言对象是symbol
,也称为name
. 它只不过是指向另一个对象的指针,即标识可能存在或不存在的另一个对象的标记。例如,如果你运行x <- 10
, thenx
是一个引用 value 的符号10
。换句话说,评估符号x
会产生数字向量10
。评估不存在的符号会产生错误。
符号看起来像一个字符串,但它不是。您可以使用 将字符串转换为符号as.symbol("x")
。
下一个语言对象是call
. 这是一个递归对象,实现为 a list
,其元素是常量、符号或另一个调用。第一个元素不能是常量,因为它必须计算为function
将被调用的实数。其他元素是此函数的参数。
如果第一个参数不计算为现有函数,R 将抛出Error: attempt to apply non-function
or Error: could not find function "x"
(如果第一个参数是未定义的符号或指向函数以外的东西)。
示例:代码行将f(x, y+z, 2)
被解析为 4 个元素的列表,第一个是f
(作为符号),第二个是x
(另一个符号),第三个是 another call
,第四个是数字常量。第三个元素y+z
, 只是一个带有两个参数的函数,因此它解析为三个名称的列表'+'
:y
和z
。
最后,还有一个expression
对象,即调用/符号/常量的列表,旨在逐个评估。
你会在这里找到很多信息:
https://github.com/hadley/devtools/wiki/Computing-on-the-language
好的,现在让我们回到你的问题:-)
您尝试过的方法不起作用,因为 的输出paste
是一个字符串,并且赋值函数期望作为其第一个参数的东西可以计算为符号,可以创建或修改。或者,第一个参数也可以评估为与替换函数关联的调用。这些有点棘手,但它们由赋值函数本身处理,而不是由解析器处理。
您看到的错误消息target of assignment expands to non-language object
是由赋值函数触发的,正是因为您的目标计算结果为字符串。
我们可以解决这个问题,建立一个在正确位置有你想要的符号的调用。最“蛮力”的方法是将所有内容放在一个字符串中并使用解析:
parse(text=paste('N',i," -> ",'z$x',i,sep=""))
到达那里的另一种方法是使用substitute
:
substitute(x -> y, list(x=as.symbol(paste("N",i,sep="")), y=substitute(z$w, list(w=paste("x",i,sep="")))))
内部替代创建call
sz$x1
等z$x2
。外部替代将此调用作为赋值的标记,并将符号N1
等N2
作为值。
parse
结果是expression
,并且substitute
是call
。两者都可以传递给以eval
获得相同的结果。
最后一点:我再说一遍,所有这些都是为了作为一个教学示例,以帮助理解语言的内部工作原理,但是使用and远非良好的编程实践,除非真的别无选择。parse
substitute