Can anyone explain to me why the following example occurs?
#Create simple dataframe
assign( "df" , data.frame( P = runif(5) , Q = runif(5) , R = runif(5) ) )
#Return the dataframe from the given character vector
get( "df" )
P Q R
1 0.17396222 0.90994676 0.90590685
2 0.33860092 0.98078739 0.38058921
3 0.80751402 0.93229290 0.82853094
4 0.05460417 0.55448507 0.01605027
5 0.04250316 0.03808318 0.40678270
#Return the column names of df
colnames( get( "df" ) )
[1] "P" "Q" "R"
#But using a replacement function...
colnames( get( "df" ) ) <- c( "S" , "T" , "U" )
Error in colnames(get("df")) <- c("S", "T", "U") :
target of assignment expands to non-language object
I'd
A) like to know why the replacement functions won't work in this way with get()?
And b) if there is some way to work around this, given my problem which I outline below;
My problem is that I have many objects, created (using a toy example) in a loop, something like this: assign( paste( "Object" , i , sep = "." ) , rnorm(1000 , i) ), where i is a vector, say i <- 1:1000 and then I would like to be able to assign names (for instance from a different vector) to each object in the loop, but names( get( paste( "Object" , i , sep = "." ) ) <- someNewName doesn't work as in the example above.
But get( paste( "Object" , i , sep = "." ) ) does return the names (or NULL) of those objects.
Thanks!
REPLACE replaces part of a text string, based on the number of characters you specify, with a different text string.
We can use mock functions when we want to replace a specific function return value. Or when we want to check if our test subject is executing a function in a certain way. We can mock a standalone function or an external module method, and we can provide a specific implementation.
To understand why this doesn't work, you need to understand what colnames<- does. Like every function in that looks like it's modifying an object, it's actually modifying a copy, so conceptually colnames(x) <- y gets expanded to:
copy <- x
colnames(copy) <- y
x <- copy
which can be written a little more compactly if you call the replacement operator in the usual way:
x <- `colnames<-`(x, y)
So your example becomes
get("x") <- `colnames<-`(get("x"), y)
The right side is valid R, but the command as a whole is not, because you can't assign something to the result of a function:
x <- 1
get("x") <- 2
# Error in get("x") <- 2 :
# target of assignment expands to non-language object
Using assign in the way you demonstrate in the question is at least uncommon in R. Normally you would just put all objects in a list.
So, instead of
for (i in 1:10) {
assign( paste( "Object" , i , sep = "." ) , rnorm(1000 , i) )}
you would do
objects <- list()
for (i in 1:10) {
objects[[i]] <- rnorm(1000 , i) }
In fact, this construct is so common that there is a (optimized) function (lapply), which does something similar:
objects <- lapply(1:10, function(x) rnorm(1000,x))
You can then access, e.g., the first object as objects[[1]] and there are several functions for working with lists.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With