2009-11-02 180 views
12

在Stata编程时,我经常发现自己在编程中使用循环索引。例如,我会遍历所有的变量列表nominalprice和realprice:循环遍历字符串变量R

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 I已经出来做同样的事情的方法是:

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呢。也许我只是没有正确地思考这个问题?你能提出一个更好的方式来使用字符串循环吗?

回答

16

正如其他人暗示,如果你有一个名为nominalpricerealprice列的数据帧这会更容易些。如果你不这样做,你总是可以使用get。在这里你根本不需要parse

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

感谢Jonathon。我喜欢get(i)选项,我会尝试使用它。我使用的数据是虚拟数据,因此可以在数据框中构造。使用数据框会有什么不同? – aTron 2009-11-02 21:59:33

+0

因为这很容易通过字符串访问。假设你有一个名为'nominalprice'的数据框'df'。然后你可以写'df [,“nominalprice”]'来获得该列。 – 2009-11-03 00:09:06

1

我不明白你原来的解决方案有什么特别的错,除了我不知道你为什么使用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) 
+0

在上面的函数中,c.name是指什么?我试图了解如何将这种技术应用于其他情况。 – aTron 2009-11-02 22:28:41

+0

c.name是一个变量名称,我将它赋值给lapply传递的参数(lapply,在这种情况下,只是传递该向量的每个元素,一次一个)。尝试玩这个看看它是如何工作的:lapply(c(1,2,3),function(x)print(x))。也看看?lapply。 – Shane 2009-11-02 22:44:52

2

如果你的主要问题是输入eval(解析的需要(文本=代替`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() 
} 
+0

感谢您的回答!这是一个非常有用的提示。这绝对会简化我的编码。 – aTron 2009-11-02 22:05:04

+0

我认为你应该使用get(),如Jonathan Chang所示。 – 2009-11-02 23:53:53

1

使用ggplot2 a第二重塑:

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)