Produce un elenco di nomi di variabili in un ciclo for, quindi assegna loro dei valori


27

Mi chiedo se esiste un modo semplice per produrre un elenco di variabili usando un ciclo for e dare il suo valore.

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

Nel codice sopra, provo a creare a1, a2, a3, quale assegnare i valori di 1, 2, 3. Tuttavia, R dà un messaggio di errore. Grazie per l'aiuto.


3
Dubito che tu debba farlo - sembra che tu stia facendo qualcosa in un modo molto sbagliato.

@mbq, ad esempio in Eviews questa è una pratica di programmazione abbastanza normale. Non che lo stia sostenendo, le tariffe di Eviews sono solo leggermente inferiori rispetto a Excel nella mia lista dei migliori software malvagi :)
mpiktas,

6
@mpiktas In R, è più naturale creare un elenco, impostarne i namesparametri e successivamente utilizzarlo, attachconvertirlo in un ambiente con list2enve evalal suo interno. Senza loop, analisi o altre cose brutte.

@mbq, hm, list2envè una funzione relativamente nuova. E tuttavia produrrà le variabili in alcuni ambienti, quando l'OP vuole ottenere le variabili nell'ambiente superiore. Quindi la bruttezza rimane ancora :)
mpiktas,

2
Per domande future di natura simile, suggerirei che questo tipo di domanda appartenga effettivamente a StackOverflow. La domanda non ha nulla a che fare con le statistiche in sé.
Marte,

Risposte:


41

Stai cercando assign().

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

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

e

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

Aggiornare

Concordo sul fatto che l'uso dei loop è (molto spesso) un cattivo stile di codifica R (vedi discussione sopra). Utilizzando list2env()(grazie a @mbq per averlo menzionato), questa è un'altra soluzione alla domanda di @Han Lin Shang:

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

21

Se i valori sono in vettoriale, il ciclo non è necessario:

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

Come nota a margine, questo è il motivo per cui amo R.


4
library(fortunes) fortune(106)
Roman Luštrik,

@Roman, strano, ho iniziato a usare parsedopo aver letto le pagine di aiuto di R. Concordo sul fatto che a volte è eccessivo, ad esempio nella formulagestione, ma l'ho trovato molto utile. Nota che non posso ripensare alla domanda come suggerito nella fortuna, dal momento che non l'ho fatta.
mpiktas,

1
@mpiktas: ha a che fare con il fatto che le regole di scoping sottostanti possono dare risultati imprevedibili se usate all'interno di una funzione. Inoltre (come menzionato nei file della guida), R e S possono dare un risultato diverso a causa della differenza nelle regole di ambito. È anche più lento di altre soluzioni. Questo avrà importanza quando dovrai farlo molte volte. E, ultimo ma non meno importante, nella maggior parte dei casi esiste una soluzione più elegante e più semplice rispetto all'utilizzo di eval (parse ()). In questo caso, funziona con elenchi o utilizza assegna.
Joris Meys,

1
@mpiktas: non ho mai detto che sia carente. Ti ho appena dato il motivo per cui in generale un costrutto eval (parse ()) è sconsigliato ad esempio da Thomas Lumley, membro del team di sviluppo di R core. (cfr il riferimento di @Roman Lustrik)
Joris Meys,

1
esattamente, le cattive pratiche come l'uso di assegnazione per creare più variabili a singolo elemento dovrebbero essere scoraggiate
mdsumner,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.