Produire une liste de noms de variables dans une boucle for, puis leur attribuer des valeurs

27

Je me demande s'il existe un moyen simple de produire une liste de variables à l'aide d'une boucle for et de donner sa valeur.

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

Dans le code ci - dessus, je tente de créer a1, a2, a3qui assignent aux valeurs de 1, 2, 3. Cependant, R donne un message d'erreur. Merci de votre aide.

Han Lin Shang
la source
3
Je doute que vous deviez le faire - il semble que vous faites quelque chose de très mal.
@mbq, dans Eviews par exemple, c'est une pratique de codage assez normale. Non pas que je le préconise, Eviews ne note qu'un peu plus bas qu'Excel dans ma liste des meilleurs logiciels malveillants :)
mpiktas
6
@mpiktas Dans R, il est plus naturel de faire une liste, de définir son namesparamètre et plus tard de l'utiliser, de la attachconvertir ou de la convertir en un environnement avec list2envet à l' evalintérieur. Sans boucles, analyse ou autres trucs laids.
@mbq, hm, list2envest une fonction relativement nouvelle. Et encore, il produira les variables dans un certain environnement, lorsque l'OP veut obtenir les variables dans l'environnement supérieur. Donc la laideur reste toujours :)
mpiktas
2
Pour les questions futures de même nature, je suggère que ce type de question appartient en fait à StackOverflow. La question n'a rien à voir avec les statistiques en soi.
Mars

Réponses:

41

Vous recherchez assign().

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

donne

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

et

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

Mise à jour

Je suis d'accord que l'utilisation de boucles est (très souvent) un mauvais style de codage R (voir la discussion ci-dessus). En utilisant list2env()(merci à @mbq pour l'avoir mentionné), ceci est une autre solution à la question de @Han Lin Shang:

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

Si les valeurs sont en vecteur, la boucle n'est pas nécessaire:

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))

En remarque, c'est la raison pour laquelle j'aime R.

mpiktas
la source
4
library(fortunes) fortune(106)
Roman Luštrik
@Roman, étrange, j'ai commencé à utiliser parseaprès avoir lu les pages d'aide R. Je suis d'accord que c'est parfois une surpuissance, par exemple en formulagestion, mais je l'ai trouvé très utile. Notez que je ne peux pas repenser la question comme suggéré dans la fortune, puisque je ne l'ai pas posée.
mpiktas
1
@mpiktas: cela a à voir avec le fait que les règles de portée sous-jacentes peuvent entraîner des résultats imprévisibles lorsqu'elles sont utilisées dans une fonction. De plus (comme mentionné dans les fichiers d'aide), R et S peuvent donner un résultat différent en raison de la différence de règles de portée. Il est également plus lent que les autres solutions. Cela importera lorsque vous devrez le faire plusieurs fois. Enfin et surtout, dans la plupart des cas, il existe une solution plus élégante et plus simple que d'utiliser eval (parse ()). Dans ce cas, cela fonctionne avec des listes ou en utilisant assign.
Joris Meys
1
@mpiktas: Je n'ai jamais dit que c'était déficient. Je viens de vous donner la raison pour laquelle en général une construction eval (parse ()) est déconseillée par exemple par Thomas Lumley, membre de l'équipe de développement principale de R. (cfr la référence de @Roman Lustrik)
Joris Meys
1
exactement, les mauvaises pratiques comme l'utilisation de l'attribut pour créer plusieurs variables à élément unique devraient être découragées
mdsumner