Produzca una lista de nombre de variable en un bucle for, luego les asigna valores

27

Me pregunto si hay una manera simple de producir una lista de variables usando un bucle for y dar su valor.

for(i in 1:3)
{
  noquote(paste("a",i,sep=""))=i
}

En el código anterior, trato de crear a1, a2, a3, que asignan a los valores de 1, 2, 3. Sin embargo, R da un mensaje de error. Gracias por tu ayuda.

Han Lin Shang
fuente
3
Dudo que tengas que hacer esto, parece que estás haciendo algo de una manera muy incorrecta.
@mbq, en Eviews, por ejemplo, esta es una práctica de codificación bastante normal. No es que yo estoy abogando por que, las tasas de Eviews solamente un poco inferior a la de Excel en mi lista de software mal :)
mpiktas
66
@mpiktas En R, es más natural hacer una lista, establecer su namesparámetro y luego usarlo, attacho convertirlo en un entorno dentro list2envy evaldentro de él. Sin bucles, análisis u otras cosas feas.
@mbq, hm, list2enves una función relativamente nueva. Y aún así producirá las variables en algún entorno, cuando el OP quiera obtener las variables en el entorno superior. Así que la fealdad aún permanece :)
mpiktas
2
Para futuras preguntas de naturaleza similar, sugeriría que este tipo de pregunta realmente pertenezca a StackOverflow. La pregunta no tiene nada que ver con las estadísticas per se.
Marte

Respuestas:

41

Tu estas buscando assign().

for(i in 1:3){
  assign(paste("a", i, sep = ""), i)    
}

da

> ls()
[1] "a1"          "a2"          "a3" 

y

> a1
[1] 1
> a2
[1] 2
> a3
[1] 3

Actualizar

Estoy de acuerdo en que usar bucles es (muy a menudo) un mal estilo de codificación R (ver discusión más arriba). Usando list2env()(gracias a @mbq por mencionarlo), esta es otra solución a la pregunta de @Han Lin Shang:

x <- as.list(rnorm(10000))
names(x) <- paste("a", 1:length(x), sep = "")
list2env(x , envir = .GlobalEnv)
Bernd Weiss
fuente
21

Si los valores están en vector, el bucle no es necesario:

vals <- rnorm(3)
n    <- length(vals)
lhs  <- paste("a",    1:n,     sep="")
rhs  <- paste("vals[",1:n,"]", sep="")
eq   <- paste(paste(lhs, rhs, sep="<-"), collapse=";")
eval(parse(text=eq))

Como nota al margen, esta es la razón por la que amo a R.

mpiktas
fuente
44
library(fortunes) fortune(106)
Roman Luštrik
@Roman, extraño, comencé a usar parsedespués de leer las páginas de ayuda de R. Estoy de acuerdo en que a veces es una exageración, por ejemplo en formulaadministración, pero me pareció muy útil. Tenga en cuenta que no puedo repensar la pregunta como se sugiere en la fortuna, ya que no la hice.
mpiktas
1
@mpiktas: tiene que ver con el hecho de que las reglas de alcance subyacentes pueden generar resultados impredecibles cuando se usan dentro de una función. Además (como se menciona en los archivos de ayuda), R y S pueden dar un resultado diferente debido a la diferencia en las reglas de alcance. También es más lento que otras soluciones. Esto importará cuando tengas que hacer esto muchas veces. Y por último, pero no menos importante, en la mayoría de los casos hay una solución más elegante y fácil que usar eval (parse ()). En este caso, eso es trabajar con listas o usar asignar.
Joris Meys
1
@mpiktas: nunca dije que fuera deficiente. Acabo de darle la razón por la cual, en general, una construcción eval (parse ()) es desaconsejada, por ejemplo, por Thomas Lumley, miembro del equipo de desarrollo central de R. (cfr la referencia de @Roman Lustrik)
Joris Meys
1
exactamente, las malas prácticas como el uso de asignación para crear múltiples variables de un solo elemento debe ser desalentado
mdsumner