2009-11-02 11 views
12

Lors de la programmation dans Stata, je trouve souvent l'indice de boucle dans la programmation. Par exemple, je vais boucler sur une liste des variables nominalprice et RealPrice:Boucle sur les variables de chaîne dans R

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

Ce tracera la série chronologique des prix nominaux et réels et exporter un graphique appelé Timeplot-nominalprice.png et un autre appelé TimePlot- realprice.png.

En R la méthode que je suis venu avec pour faire la même chose serait:

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

Ce code R semble unintuitive et malpropre pour moi et je n'ai pas trouvé une bonne façon de faire genre de chose dans R encore. Peut-être que je ne pense pas au problème de la bonne façon? Pouvez-vous suggérer une meilleure façon de faire une boucle en utilisant des cordes?

Répondre

16

Comme d'autres personnes ont laissé entendre, ce serait plus facile si vous aviez une trame de données avec des colonnes nommées nominalprice et realprice. Si vous ne le faites pas, vous pouvez toujours utiliser get. Vous ne devriez pas avoir besoin de parse ici.

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

Merci Jonathon. J'aime l'option get (i) et j'essaierai de travailler avec ça. Les données que j'utilisais étaient des données fictives qui pourraient donc être structurées dans une base de données. Qu'est-ce qui serait différent si vous utilisiez un dataframe? – aTron

+0

Parce que c'est facile d'accès par chaîne. Supposons que vous ayez une trame de données 'df' avec une colonne nommée' nominalprice'. Ensuite, vous pouvez simplement écrire 'df [," nominalprice "]' pour obtenir cette colonne. –

1

Je ne vois pas ce qui ne va pas dans votre solution d'origine, sauf que je ne sais pas pourquoi vous utilisez la fonction eval(). Cela ne me semble pas nécessaire.

Vous pouvez également utiliser une fonction d'application, telle que lapplication. Voici un exemple de travail. J'ai créé des données fictives comme une série chronologique zoo() (ce n'est pas nécessaire, mais puisque vous travaillez avec des données de séries chronologiques de toute façon):

# 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

Dans la fonction ci-dessus, à quoi fait référence c.name? J'essaie de comprendre comment je pourrais appliquer cette technique à d'autres situations. – aTron

+0

c.name est un nom de variable que j'assigne à ce que get est passé par lapply (lapply, dans ce cas, passe juste chaque élément de ce vecteur, un à la fois). Essayez de jouer avec ceci pour voir comment cela fonctionne: lapply (c (1,2,3), fonction (x) print (x)). Regardez aussi lapply. – Shane

2

Si votre problème principal est le besoin de taper eval (parse (texte = i)) au lieu de `` i'`, vous pouvez créer une fonction plus simple à utiliser pour évaluer les expressions de chaînes:

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

Ensuite, l'exemple R pourrait être simplifié à:

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

Merci pour votre réponse! Ceci est un conseil très utile. Cela va certainement simplifier mon codage. – aTron

+0

Je pense que vous devriez utiliser get() comme indiqué par Jonathan Chang à la place. –

1

Utilisation de ggplot2 a nd refaçonner:

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