Цикл по строковым переменным в R - PullRequest
13 голосов
/ 02 ноября 2009

При программировании в Stata я часто использую индекс цикла в программировании. Например, я переберу список переменных nominalprice и realprice:

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

Это построит временные ряды номинальных и реальных цен и экспортирует один график под названием TimePlot-nominalprice.png, а другой - TimePlot-realprice.png

В R метод, который я придумал, чтобы сделать то же самое, был бы:

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

Этот код R кажется мне неинтуитивным и грязным, и я пока не нашел хорошего способа сделать такое в R. Может я просто не правильно думаю о проблеме? Можете ли вы предложить лучший способ зацикливания, используя строки?

Ответы [ 4 ]

18 голосов
/ 02 ноября 2009

Как говорили другие, это было бы проще, если бы у вас был кадр данных со столбцами с именами nominalprice и realprice. Если вы этого не сделаете, вы всегда можете использовать get. Тебе вообще не нужно parse.

clist <- c("nominalprice", "realprice")
for (i in clist) {
   png(paste("c:/TimePlot-",i,".png"), sep="")
   plot(time, get(i))
   dev.off() 
}
2 голосов
/ 02 ноября 2009

Если вашей основной проблемой является необходимость ввода eval (parse (text = i)) вместо `` i'`, вы можете создать более простые в использовании функции для вычисления выражений из строк:

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

Тогда пример R можно упростить до:

clist <- c("nominalprice", "realprice")
for (i in clist) {
  png(paste("c:/TimePlot-", i, ".png", sep=""))
  plot(time, e(i))
  dev.off() 
}
1 голос
/ 02 ноября 2009

Использование ggplot2 и изменение формы:

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)
1 голос
/ 02 ноября 2009

Я не вижу, что особенно не так с вашим исходным решением, кроме того, что я не знаю, почему вы используете функцию eval () Это не кажется мне необходимым.

Вы также можете использовать функцию применения, например, lapply. Вот рабочий пример. Я создал фиктивные данные как zoo() временной ряд (это не обязательно, но так как вы все равно работаете с данными временных рядов):

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