I'd suggest using something like for( i in 1:10 ) z[,i] <- N[,i]
...
BUT, since you said you want to learn something new, you can play around with parse
and substitute
.
NOTE: these little tools are funny, but experienced users (not me) avoid them.
This is called "computing on the language". It's very interesting, and it helps understanding the way R works. Let me try to give an intro:
The basic language construct is a constant, like a numeric or character vector. It is trivial because it is not different from its "unevaluated" version, but it is one of the building blocks for more complicated expressions.
The (officially) basic language object is the symbol
, also known as a name
. It's nothing but a pointer to another object, i.e., a token that identifies another object which may or may not exist. For instance, if you run x <- 10
, then x
is a symbol that refers to the value 10
. In other words, evaluating the symbol x
yields the numeric vector 10
. Evaluating a non-existant symbol yields an error.
A symbol looks like a character string, but it is not. You can turn a string into a symbol with as.symbol("x")
.
The next language object is the call
. This is a recursive object, implemented as a list
whose elements are either constants, symbols, or another calls. The first element must not be a constant, because it must evaluate to the real function
that will be called. The other elements are the arguments to this function.
If the first argument does not evaluate to an existing function, R will throw either Error: attempt to apply non-function
or Error: could not find function "x"
(if the first argument is a symbol that is undefined or points to something other than a function).
Example: the code line f(x, y+z, 2)
will be parsed as a list of 4 elements, the first being f
(as a symbol), the second being x
(another symbol), the third another call
, and the fourth a numeric constant. The third element y+z
, is just a function with two arguments, so it parses as a list of three names: '+'
, y
and z
.
Finally, there is also the expression
object, that is a list of calls/symbols/constants, that are meant to be evaluated one by one.
You'll find lots of information here:
https://github.com/hadley/devtools/wiki/Computing-on-the-language
OK, now let's get back to your question :-)
What you have tried does not work because the output of paste
is a character string, and the assignment function expects as its first argument something that evaluates to a symbol, to be either created or modified. Alternativelly, the first argument can also evaluate to a call associated with a replacement function. These are a little trickier, but they are handled by the assignment function itself, not by the parser.
The error message you see, target of assignment expands to non-language object
, is triggered by the assignment function, precisely because your target evaluates to a string.
We can fix that building up a call that has the symbols you want in the right places. The most "brute force" method is to put everything inside a string and use parse:
parse(text=paste('N',i," -> ",'z$x',i,sep=""))
Another way to get there is to use substitute
:
substitute(x -> y, list(x=as.symbol(paste("N",i,sep="")), y=substitute(z$w, list(w=paste("x",i,sep="")))))
the inner substitute creates the call
s z$x1
, z$x2
etc. The outer substitute puts this call as the taget of the assignment, and the symbols N1
, N2
etc as the values.
parse
results in an expression
, and substitute
in a call
. Both can be passed to eval
to get the same result.
Just one final note: I repeat that all this is intended as a didactic example, to help understanding the inner workings of the language, but it is far from good programming practice to use parse
and substitute
, except when there is really no alternative.