Перебирать строковые переменные в R
При программировании в Stata я часто нахожу себя использующим индекс цикла в программировании. Например, я буду перебирать список переменных: номинальная цена и реальная цена:
local list = "nominalprice realprice"
foreach i of local list {
summarize `i'
twoway (scatter `i' time)
graph export "C:\TimePlot-`i'.png"
}
Это будет отображать временные ряды номинальных и реальных цен и экспортировать один график под названием TimePlot-номинант price.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. Может быть, я просто не думаю о проблеме правильно? Можете ли вы предложить лучший способ цикла с использованием строк?
Ответы
Ответ 1
Как говорили другие люди, это было бы проще, если бы у вас был фреймворк данных с столбцами с именем 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
Если основной проблемой является необходимость набирать 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()
}
Ответ 3
Я не вижу, что особенно плохо с вашим оригинальным решением, за исключением того, что я не знаю, почему вы используете функцию eval(). Мне это не кажется нужным.
Вы также можете использовать функцию apply, такую как 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)
Ответ 4
Использование 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)