Utwórz listę nazw zmiennych w pętli for, a następnie przypisz im wartości

27

Zastanawiam się, czy istnieje prosty sposób na utworzenie listy zmiennych za pomocą pętli for i podanie jej wartości.

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

W powyższym kodzie, staram się tworzyć a1, a2, a3, które przypisać do wartości 1, 2, 3. Jednakże R daje komunikat o błędzie. Dzięki za pomoc.

Han Lin Shang
źródło
3
Wątpię, czy musisz to zrobić - wygląda na to, że robisz coś w bardzo zły sposób.
@mbq, na przykład w Eviews jest to dość normalna praktyka kodowania. Nie to, że popieram go, stopy EViews tylko nieco niższe niż Excel w moim top listy oprogramowania zło :)
mpiktas
6
@mpiktas W języku R bardziej naturalne jest tworzenie listy, ustawianie jej namesparametrów, a później albo po prostu z niej korzystasz, attachalbo zamieniasz ją na środowisko z nim list2envi evalwewnątrz niego. Bez pętli, parsowania i innych brzydkich rzeczy.
@mbq, hm, list2envjest stosunkowo nową funkcją. I nadal będzie generować zmienne w pewnym środowisku, gdy OP chce uzyskać zmienne w najwyższym środowisku. Więc brzydota wciąż pozostaje :)
mpiktas
2
W przypadku przyszłych pytań o podobnym charakterze sugerowałbym, że tego rodzaju pytanie faktycznie należy do StackOverflow. Pytanie nie ma nic wspólnego ze statystykami.
Mars

Odpowiedzi:

41

Twój szukasz assign().

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

daje

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

i

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

Aktualizacja

Zgadzam się, że używanie pętli jest (bardzo często) złym stylem kodowania R (patrz dyskusja powyżej). Wykorzystując list2env()(dzięki @mbq za wzmiankę o tym), jest to inne rozwiązanie pytania @ Han Lin Shanga:

x <- as.list(rnorm(10000))
names(x) <- paste("a", 1:length(x), sep = "")
list2env(x , envir = .GlobalEnv)
Bernd Weiss
źródło
21

Jeśli wartości są w wektorze, pętla nie jest konieczna:

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

Na marginesie, to jest powód, dla którego kocham R.

mpiktas
źródło
4
library(fortunes) fortune(106)
Roman Luštrik
@Roman, dziwne, zacząłem używać parsepo przeczytaniu stron pomocy R. Zgadzam się, że czasami jest to przesada, na przykład w formulazarządzaniu, ale uważam ją za bardzo przydatną. Zauważ, że nie mogę ponownie przemyśleć pytania, jak zasugerowano w fortunie, ponieważ go nie zadałem.
mpiktas
1
@mpiktas: ma to związek z faktem, że leżące u podstaw reguły określania zakresu mogą dawać nieprzewidywalne wyniki, jeśli zostaną użyte w funkcji. Ponadto (jak wspomniano w plikach pomocy) R i S mogą dawać inny wynik z powodu różnic w regułach określania zakresu. Jest również wolniejszy niż inne rozwiązania. Będzie to miało znaczenie, gdy będziesz musiał to zrobić wiele razy. I na koniec, w większości przypadków istnieje bardziej eleganckie i łatwiejsze rozwiązanie niż użycie eval (parse ()). W tym przypadku działa to z listami lub przy użyciu przypisania.
Joris Meys
1
@mpiktas: Nigdy nie mówiłem, że to niedobór. Właśnie podałem ci powód, dla którego generalnie odradza się konstrukcję eval (parse ()), np. Thomas Lumley, członek zespołu ds. Rozwoju rdzenia R. (por. refrence @Roman Lustrik)
Joris Meys
1
dokładnie, należy odradzać złą praktykę, taką jak używanie przypisania do tworzenia wielu zmiennych jednoelementowych
mdsumner