【问题标题】:R - Use names in a list to feed named objects to a loop?R - 使用列表中的名称将命名对象提供给循环?
【发布时间】:2017-12-23 23:55:55
【问题描述】:

我有一个包含大约 90 个金融符号的数据框(为简单起见,将使用 3 个)

> View(syM)     
  symbol
1 APPL
2 YAHOO
3 IBM

我创建了一个函数,用于获取这些符号的 JSON 数据并生成输出。基本上:

nX  <- function(x) {
  #get data for "x", format it, and store it in "nX"
  nX <- x
  return(nX)
}

我使用循环来获取数据并相应地存储以每个符号命名的动物园系列。

for (i in 1:nrow(syM)) {
  assign(x = paste0(syM[i,]), 
  value = nX(x = syM[i,]))
  Sys.sleep(time = 1)
}

结果:

[1] "APPL"          "YAHOO"         "IBM" 

每个都是一个包含 5 列数据的动物园系列。

此外,我想对每个系列进行一些绘图并输出结果,最好使用 for 循环或更好的方法。

yN  <- function(y) {
  #plot "y" series, columns 2 and 3, and store it in "yN"
  yN <- y[,2:3]
  return(yN)
}

遵循与我之前尝试的循环类似的逻辑:

for (i in 1:nrow(syM)) {
  assign(x = paste0(pairS[i,],".plot"),
  value = yN(y = paste0(syM[i,])))
}

但是到目前为止数据并没有被发送到函数,只有符号的名称,所以我自然得到:

y[,2:3] : incorrect number of dimensions

我也试过了:

for (i in 1:nrow(syM)) {
  assign(x = paste0(syM[i,],".plot"),
  value = yN(y = ls(pattern = paste0(syM[i,]))))
}

结果相似。当我手动输入系列名称时,它会将第一个符号的图保存为“APPL.Plot”。

assign(paste0(syM[1,], ".Plot"),
       value = yN(p = APPL))

【问题讨论】:

  • 当然,您没有包括对 library 的调用,以获取暗示要为此加载的各种包。另外我建议您将来将dput 的输出添加到syM
  • 会的,谢谢。我相信唯一使用的库是library(quantmod),但这只是为了获取符号的数据。

标签: r for-loop dataframe zoo names


【解决方案1】:

考虑使用lapplysetNames 创建一个nX 个返回对象的命名列表:

nX_list <- setNames(lapply(syM$symbol, nX), syM$symbol)

# OUTPUT ZOO OBJECTS BY NAMED INDEX
nX_list$AAPL
nX_list$YAHOO
nX_list$IBM

# CREATE SEPARATE OBJECTS FROM LIST 
# BUT NO NEED TO FLOOD GLOBAL ENVIR W/ 90 OBJECTS, JUST USE 1 LIST
list2env(nX_list, envir=.GlobalEnv)

对于绘图函数,首先在函数内部添加一个get 以通过其字符串名称检索对象,然后类似地运行lapplysetNames

yN  <- function(y) {
  #plot "y" series, columns 2 and 3, and store it in "yN"  
  yobj <- get(nX_list[[y]])     # IF USING ABOVE LIST
  yobj <- get(y)                # IF USING SEPARATE OBJECT

  yN <- yobj[,2:3]
  return(yN)
}

plot_list <- setNames(lapply(syM$symbol, yN), paste0(syM$symbol, ".plot"))

# OUTPUT PLOTS BY NAMED INDEX
plot_list$AAPL.plot
plot_list$YAHOO.plot
plot_list$IBM.plot

# CREATE SEPARATE OBJECTS FROM LIST 
# BUT NO NEED TO FLOOD GLOBAL ENVIR W/ 90 OBJECTS, JUST USE 1 LIST
list2env(plot_list, envir=.GlobalEnv)

【讨论】:

  • 我可以用get()paste0() 做到这一点。我使用for 循环主要将assign() 的名称从符号列表分别到每个系列。我想我会重新考虑使用lapply() 将它们绑定在一起。
  • 但是您选择使用get()yobj 会更好。
  • 正如我在代码中评论的那样,一个列表比充斥全球环境的 90 个对象更易于管理,特别是如果对象具有相同的结构,例如 zoo 5 列。
【解决方案2】:

正如您所注意到的,您在调用 yN 时带有一个字符参数:

for (i in 1:nrow(syM)) {
  assign(x = paste0(pairS[i,],".plot"),
  value = yN(y = paste0(syM[i,])))
}

paste0(syM[i,]) 将解析为一个角色,而不是您尝试引用的 zoo 对象。相反,请使用类似get():

for (i in 1:nrow(syM)) {
  assign(x = paste0(pairS[i,],".plot"),
  value = yN(y = get(paste0(syM[i,]))))
}

或者,也许首先将您的动物园对象存储在一个列表中,然后使用lapply()...之类的东西对列表的所有元素进行操作...

【讨论】:

  • 谢谢!那成功了。我试图避免将它们全部放在一个带有lapply() 的列表中。关键是使用get()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
相关资源
最近更新 更多