Erstellen Sie eine Liste mit Variablennamen in einer for-Schleife und weisen Sie ihnen Werte zu

27

Ich frage mich, ob es eine einfache Möglichkeit gibt, mit einer for-Schleife eine Liste von Variablen zu erstellen und ihren Wert anzugeben.

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

In dem obigen Code, ich versuche zu erstellen a1, a2, a3, die assign zu den Werten von 1, 2, 3. Allerdings gibt R eine Fehlermeldung. Danke für Ihre Hilfe.

Han Lin Shang
quelle
3
Ich bezweifle, dass Sie dies tun müssen - es scheint, dass Sie etwas auf eine sehr falsche Weise machen.
@mbq, in Eviews zum Beispiel ist dies eine ziemlich normale Codierungspraxis. Nicht dass ich es befürworte, Eviews bewertet nur ein bisschen weniger als Excel in meiner Top-Liste der bösen Software :)
mpiktas
6
@mpiktas In R ist es natürlicher, eine Liste zu erstellen, deren namesParameter festzulegen und sie später entweder nur zu verwenden attachoder in eine Umgebung mit list2envund evalinnerhalb der Liste zu konvertieren . Ohne Schleifen, Parsen oder andere hässliche Dinge.
@mbq, hm, list2envist eine relativ neue Funktion. Und dennoch werden die Variablen in einer bestimmten Umgebung erzeugt, wenn das OP die Variablen in der obersten Umgebung abrufen möchte. So bleibt die Hässlichkeit immer noch :)
mpiktas
2
Für zukünftige Fragen ähnlicher Art würde ich vorschlagen, dass diese Art von Frage tatsächlich zu StackOverflow gehört. Die Frage hat an sich nichts mit Statistik zu tun.
Mars

Antworten:

41

Sie suchen assign().

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

gibt

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

und

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

Aktualisieren

Ich bin damit einverstanden, dass die Verwendung von Schleifen (sehr oft) einen schlechten R-Codierungsstil darstellt (siehe obige Diskussion). Mit list2env()(danke an @mbq für die Erwähnung) ist dies eine weitere Lösung für die Frage von @Han Lin Shang:

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

Wenn die Werte in Vektor sind, ist die Schleife nicht erforderlich:

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

Als Randnotiz ist dies der Grund, warum ich R. liebe.

mpiktas
quelle
4
library(fortunes) fortune(106)
Roman Luštrik
@ Roman, seltsam, ich habe angefangen, parsenach dem Lesen von R-Hilfeseiten. Ich stimme zu, dass es manchmal ein Overkill ist, zum Beispiel im formulaManagement, aber ich fand es sehr nützlich. Beachten Sie, dass ich die im Glück vorgeschlagene Frage nicht überdenken kann, da ich sie nicht gestellt habe.
mpiktas
1
@mpiktas: Das hat damit zu tun, dass die zugrunde liegenden Bereichsregeln zu unvorhersehbaren Ergebnissen führen können, wenn sie in einer Funktion verwendet werden. Auch (wie in den Hilfedateien erwähnt) können R und S aufgrund der unterschiedlichen Gültigkeitsregeln ein unterschiedliches Ergebnis liefern. Es ist auch langsamer als andere Lösungen. Dies ist wichtig, wenn Sie dies oft tun müssen. Und nicht zuletzt gibt es in den meisten Fällen eine elegantere und einfachere Lösung als die Verwendung von eval (parse ()). In diesem Fall funktioniert das mit Listen oder mit zuweisen.
Joris Meys
1
@mpiktas: Ich habe nie gesagt, dass es mangelhaft ist. Ich habe Ihnen nur den Grund genannt, warum im Allgemeinen von einem eval (parse ()) - Konstrukt abgeraten wird, zB von Thomas Lumley, Mitglied des R-Core-Entwicklungsteams. (vgl. @Roman Lustrik)
Joris Meys
1
genau, von schlechten Praktiken wie der Verwendung von
assign