Вопрос

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

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.Может я просто не так думаю о проблеме?Можете ли вы предложить лучший способ зацикливания с использованием строк?

Это было полезно?

Решение

Как отмечали другие люди, это было бы проще, если бы у вас был фрейм данных со столбцами с именами 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() 
}

Другие советы

Если ваша основная проблема заключается в необходимости вводить 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() 
}

Используя 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)

Я не вижу, что особенно не так в вашем первоначальном решении, за исключением того, что я не знаю, почему вы используете функцию 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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top