2009-11-02 23 views
12

Durante la programmazione in Stata mi trovo spesso a utilizzare l'indice di loop nella programmazione. Ad esempio, io loop su un elenco delle variabili nominalprice e realprice:Variabili loop su stringa in R

local list = "nominalprice realprice" 
foreach i of local list { 
    summarize `i' 
    twoway (scatter `i' time) 
    graph export "C:\TimePlot-`i'.png" 
} 

Ciò tracciare la serie storica dei prezzi nominali e reali ed esportare un grafico chiamato TimePlot-nominalprice.png e un altro chiamato TimePlot- realprice.png.

Nel R il metodo che è venuta in mente di fare la stessa cosa sarebbe:

clist <- c("nominalprice", "realprice") 
for (i in clist) { 
    e <- paste("png(\"c:/TimePlot-",i,".png\")", sep="") 
    eval(parse(text=e)) 
    plot(time, eval(parse(text=i))) 
    dev.off() 
} 

Questo codice R sembra poco intuitivo e disordinato a me e non ho trovato un buon modo per fare questo tipo di cosa in R ancora. Forse non sto pensando al problema nel modo giusto? Puoi suggerire un modo migliore per eseguire il loop usando le stringhe?

risposta

16

Come altre persone hanno lasciato intendere, questo sarebbe più facile se si ha un dataframe con colonne denominate nominalprice e realprice. Se non lo fai, puoi sempre usare get. Non dovresti aver bisogno di parse qui.

clist <- c("nominalprice", "realprice") 
for (i in clist) { 
    png(paste("c:/TimePlot-",i,".png"), sep="") 
    plot(time, get(i)) 
    dev.off() 
} 
+0

Grazie Jonathon. Mi piace l'opzione get (i) e proverò a lavorarci. I dati che stavo usando sono dati fittizi quindi potrebbero essere strutturati in un dataframe. Cosa sarebbe diverso se si usasse un dataframe? – aTron

+0

Perché è facile accedere per stringa. Supponiamo che tu abbia un frame dati 'df' con una colonna denominata' nominalprice'. Quindi puoi semplicemente scrivere 'df [," nominalprice "]' per ottenere quella colonna. –

1

Non vedo cosa c'è di particolarmente sbagliato nella soluzione originale, tranne che non so perché si sta utilizzando la funzione eval(). Questo non mi sembra necessario.

È inoltre possibile utilizzare una funzione di applicazione, ad esempio lappone. Ecco un esempio funzionante. Ho creato dati fittizi come una serie storica zoo() (questo non è necessario, ma dal momento che si sta lavorando con dati di serie temporali comunque):

# x <- some time series data 
time <- as.Date("2003-02-01") + c(1, 3, 7, 9, 14) - 1 
x <- zoo(data.frame(nominalprice=rnorm(5),realprice=rnorm(5)), time) 
lapply(c("nominalprice", "realprice"), function(c.name, x) { 
    png(paste("c:/TimePlot-", c.name, ".png", sep="")) 
    plot(x[,c.name], main=c.name) 
    dev.off() 
}, x=x) 
+0

Nella funzione sopra a cosa si riferisce c.name? Sto cercando di capire come applicare questa tecnica ad altre situazioni. – aTron

+0

c.name è un nome di variabile che sto assegnando a quello che viene passato da lapply (lapply, in questo caso, sta passando solo ogni elemento di quel vettore, uno alla volta). Prova a giocare con questo per vedere come funziona: lapply (c (1,2,3), function (x) print (x)). Guarda anche lapply. – Shane

2

Se il problema principale è la necessità di digitare eval (parse (testo = i)) invece di `` i'`, è possibile creare un funzioni più semplici da usare per valutare le espressioni dalle stringhe:

e = function(expr) eval(parse(text=expr)) 

Poi l'esempio R potrebbe essere semplificata per:

clist <- c("nominalprice", "realprice") 
for (i in clist) { 
    png(paste("c:/TimePlot-", i, ".png", sep="")) 
    plot(time, e(i)) 
    dev.off() 
} 
+0

Grazie per la tua risposta! Questo è un consiglio molto utile. Semplificherebbe sicuramente la mia codifica. – aTron

+0

Penso che dovresti usare get() come mostrato invece da Jonathan Chang. –

1

Utilizzo di ggplot2 a ND rimodellare:

library(ggplot2) 
library(reshape) 
df <- data.frame(nominalprice=rexp(10), time=1:10) 
df <- transform(df, realprice=nominalprice*runif(10,.9,1.1)) 
dfm <- melt(df, id.var=c("time")) 
qplot(time, value, facets=~variable, data=dfm)