¿Alguien puede explicarme por qué ocurre el siguiente ejemplo?
#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" ) PQR 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
Me gustaría saber por qué las funciones de reemplazo no funcionarán de esta manera con get()
?
Yb) si hay alguna forma de evitar esto, dado mi problema que describo a continuación;
Mi problema es que tengo muchos objetos, creados (usando un ejemplo de juguete) en un bucle, algo así como: assign( paste( "Object" , i , sep = "." ) , rnorm(1000 , i) )
, donde i
es un vector, digamos i <- 1:1000
y luego me gustaría poder asignar nombres (por ejemplo, de un vector diferente) a cada objeto en el bucle, pero los names( get( paste( "Object" , i , sep = "." ) ) <- someNewName
no funciona como en el ejemplo anterior.
Pero get( paste( "Object" , i , sep = "." ) )
Devuelve los nombres (o NULL
) de esos objetos.
¡Gracias!
Para entender por qué esto no funciona, debe comprender qué colnames<-
hace. Como cada función en eso parece que está modificando un objeto, en realidad está modificando una copia, por lo que conceptualmente colnames(x) <- y
se expande a:
copy <- x colnames(copy) <- y x <- copy
que puede escribirse un poco más compacto si llama al operador de reemplazo de la manera habitual:
x <- `colnames<-`(x, y)
Entonces tu ejemplo se convierte
get("x") <- `colnames<-`(get("x"), y)
El lado derecho es R válido, pero el comando como un todo no lo es, porque no puede asignarle algo al resultado de una función:
x <- 1 get("x") <- 2 # Error in get("x") <- 2 : # target of assignment expands to non-language object
Usar la assign
de la forma en que se demuestra en la pregunta es al menos poco común en R. Normalmente, pondría todos los objetos en una lista.
Entonces, en lugar de
for (i in 1:10) { assign( paste( "Object" , i , sep = "." ) , rnorm(1000 , i) )}
tu harías
objects <- list() for (i in 1:10) { objects[[i]] <- rnorm(1000 , i) }
De hecho, esta construcción es tan común que hay una función (optimizada) ( lapply
), que hace algo similar:
objects <- lapply(1:10, function(x) rnorm(1000,x))
A continuación, puede acceder, por ejemplo, al primer objeto como objects[[1]]
y existen varias funciones para trabajar con listas.