Comment nommer des variables à la volée?


96

Est-il possible de créer de nouveaux noms de variables à la volée?

J'aimerais lire les cadres de données d'une liste dans de nouvelles variables avec des nombres à la fin. Quelque chose comme orca1, orca2, orca3 ...

Si j'essaye quelque chose comme

paste("orca",i,sep="")=list_name[[i]]

J'obtiens cette erreur

target of assignment expands to non-language object

Y a-t-il une autre solution?


10
Tant que nous distribuons des balises r-faq, donnons le lien (FAQ 7.21: cran.r-project.org/doc/FAQ/… )
Ben Bolker

Réponses:


118

Utilisez assign:

assign(paste("orca", i, sep = ""), list_name[[i]])

28
Voici comment procéder. Il y a une méta-question ici qui est: "Dois-je faire ça?" La réponse est presque toujours «non». Les éléments nommés dans une liste sont presque toujours préférés.
Ari

26
La réponse est presque toujours «non», sauf quand ce n'est pas le cas.
Shane

9
Oui bien sur. Mais la plupart des gens qui cherchent cette réponse ne le font pas parce qu'ils ont rejeté une liste pour leur candidature.
Ari

@Ari B. Friedman Je génère des noms de variables pour les ensembles de données que je sauvegarde dans mypackage / data. Chacun dans son fichier avec le même nom pour le fichier et les données qu'il contient (étant donné les recommandations R pour les données dans le package). Chaque ensemble de données fait environ 10M et le total est de ~ 17Go Je ne vois guère d'autre moyen.
cmbarbu

3
Y a-t-il une raison pour laquelle vous ne l'avez pas utilisé paste0?
BroVic

33

Il me semble que vous pourriez être mieux avec une liste plutôt que d' utiliser orca1, orca2etc, ... il serait alors orca[1], orca[2]...

Habituellement, vous faites une liste de variables différenciées par rien d'autre qu'un nombre, car ce nombre serait un moyen pratique d'y accéder plus tard.

orca <- list()
orca[1] <- "Hi"
orca[2] <- 59

Sinon, assignc'est exactement ce que vous voulez.


11
Je suis d'accord. Habituellement, lorsque les gens pensent vouloir nommer des variables à la volée, ce qu'ils veulent vraiment, c'est une structure de données différente.
Michael Dunn

9
+1 (FAQ 7.21: cran.r-project.org/doc/FAQ/… ) en discute joliment
Ben Bolker

11

Ne créez pas de trames de données. Gardez la liste, nommez ses éléments mais ne l'attachez pas.

La principale raison à cela est que si vous créez des variables en déplacement, vous devrez presque toujours parcourir chacune d'elles par la suite pour effectuer quelque chose d'utile. Là, vous serez à nouveau obligé de parcourir chacun des noms que vous avez créés à la volée.

Il est beaucoup plus facile de nommer les éléments de la liste et de parcourir les noms.

En ce qui concerne l'attachement, sa très mauvaise pratique de programmation dans R et peut entraîner beaucoup de problèmes si vous ne faites pas attention.


Alors, faites un attachement, mais seulement après avoir fait l'itération dans la liste?
Mox

4

FAQ dit:

Si tu as

varname <- c("a", "b", "d")

tu peux faire

get(varname[1]) + 2

pour

a + 2

ou

assign(varname[1], 2 + 2)

pour

a <- 2 + 2

Il semble donc que vous utilisiez GET lorsque vous souhaitez évaluer une formule qui utilise une variable (telle qu'une concaténation) et ASSIGN lorsque vous souhaitez affecter une valeur à une variable pré-déclarée.

Syntaxe pour assign: assign (x, value)

X: un nom de variable, donné sous forme de chaîne de caractères. Aucune coercition n'est effectuée et le premier élément d'un vecteur de caractère de longueur supérieure à un sera utilisé, avec un avertissement.

valeur: valeur à affecter à x.


0

Une autre solution délicate consiste à nommer les éléments de la liste et attachcela:

list_name = list(
    head(iris),
    head(swiss),
    head(airquality)
    )

names(list_name) <- paste("orca", seq_along(list_name), sep="")
attach(list_name)

orca1
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa

14
délicat, mais pas sage. si la réponse est attachque vous posez généralement la mauvaise question ...
Ben Bolker

-1

Et cette option?

list_name<-list()
for(i in 1:100){
    paste("orca",i,sep="")->list_name[[i]]
}

Cela fonctionne parfaitement. Dans l'exemple que vous avez mis, la première ligne est manquante, puis vous donne le message d'erreur.


3
Cela ne répond pas à la question d'OP. Nous avons une liste avec des dataframes, et nous voulons l'attribuer aux dataframes, nommées orca1, orca2, etc.
zx8754

"List with dataframes" = "liste OF dataframes"?
Mox le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.