【问题标题】:Loop over string variables in R在R中循环字符串变量
【发布时间】:2010-12-12 09:53:15
【问题描述】:

在 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 中做这种事情的好方法。也许我只是没有以正确的方式思考这个问题?你能建议一种更好的使用字符串循环的方法吗?

【问题讨论】:

    标签: r statistics stata


    【解决方案1】:

    我看不出您的原始解决方案有什么特别错误,只是我不知道您为什么使用 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)
    

    【讨论】:

    • 在上面的函数中,c.name指的是什么?我正在尝试了解如何将这种技术应用于其他情况。
    • c.name 是一个变量名,我分配给 lapply 传递的 get (在这种情况下,lapply 只是传递该向量的每个元素,一次一个)。试试看它是如何工作的:lapply(c(1,2,3), function(x) print(x))。另请查看 ?lapply。
    【解决方案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() 
    }
    

    【讨论】:

    • 感谢您的回答!这是一个非常有用的提示。它肯定会简化我的编码。
    • 我认为您应该改用 Jonathan Chang 所示的 get()。
    【解决方案3】:

    使用 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)
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 谢谢乔纳森。我喜欢 get(i) 选项,我会尝试使用它。我使用的数据是虚拟数据,因此可以在数据框中进行结构化。如果使用数据框会有什么不同?
      • 因为这样很容易通过字符串访问。假设您有一个数据框df,其中有一列名为nominalprice。然后你可以写df[,"nominalprice"] 来获取那个列。
      猜你喜欢
      • 2022-08-04
      • 2013-04-01
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-27
      • 1970-01-01
      • 2020-05-10
      相关资源
      最近更新 更多