我建议使用类似for(i in 1:10) z[,i] <- N[,i]
...
但是,既然你说你想学习新的东西,你可以玩弄parse
和substitute
。
注意:这些小工具很有趣,但有经验的用户(不是我)避免它们。
这被称为“在语言上计算”。这非常有趣,它有助于理解R的工作方式。让我试着给出一个简介:
基本的语言结构是一个常数,就像数字或字符向量一样。这是微不足道的,因为它与“未评估”版本没有区别,但它是更复杂表达式的基石之一。
(正式)基本语言对象是symbol
,也被称为name
。它只不过是一个指向另一个对象的指针,也就是标识另一个可能存在也可能不存在的对象的标记。例如,如果您运行的是x <- 10
,则x
是一个符号,指的是值10
。换句话说,评估符号x
会得到数字矢量10
。评估不存在的符号会产生错误。
符号看起来像一个字符串,但它不是。您可以使用as.symbol("x")
将字符串变成符号。
下一个语言对象是call
。这是一个递归对象,实现为list
,其元素是常量,符号或其他调用。第一个元素必须是而不是是一个常数,因为它必须评估为真正的function
将被调用。其他元素是这个函数的参数。
如果第一个参数不计算为现有函数,则R将抛出Error: attempt to apply non-function
或Error: could not find function "x"
(如果第一个参数是未定义的符号或指向函数以外的其他函数)。
实施例:码字行f(x, y+z, 2)
将被解析为4个元素的列表,第一个是f
(作为标志),第二个是x
(另一符号),第三另一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
小号z$x1
,z$x2
等。外部替代品将此调用作为赋值的目标,并将符号N1
,N2
等作为值。
parse
导致expression
和substitute
在call
中。两者都可以传递给eval
以获得相同的结果。
只是最后一个音符:我再说一遍,这一切的目的是作为一个说教例如,为了帮助理解语言的内部运作,但它是远从良好的编程习惯使用parse
和substitute
,除非有真的是别无选择。
使用'get'和'assign',但不这样做 - 使用列表来代替。有关于此的R常见问题解答以及许多SO问题(现在您知道正确的事情要寻找)。 – 2013-04-11 21:20:01