【问题标题】:Create and use different tables in for-loops in R in a shorter way以更短的方式在 R 的 for 循环中创建和使用不同的表
【发布时间】:2016-11-02 15:37:37
【问题描述】:

我正在寻找一个简短的解决方案来在 for 循环中创建和使用不同的表,其中循环变量是名称的一部分。

我找到了以下解决方案:

如果我想在循环中创建表格,我可以将分配与粘贴一起使用。例如:

for (f in files){
assign(paste0("A_",f), readWorksheetFromFile(paste0(f,".xlsx")))}

如果我想使用这些表,我可以通过以下方式使用 eval、parse 和 paste0:

for(f in files){
  x <- eval(parse(text=paste0("A_",f)))}

问题是我必须经常使用这些结构并且代码变得很长。有没有人在 R 中有更短的解决方案来做到这一点?

例如在 SAS 中,我可以使用类似的东西(我记得)

x = A_&f;

而不是

x <- eval(parse(text=paste0("A_",f)))

编辑

根据以下答案,我找到了这个解决方案:

在循环创建对象的过程中,我可以使用函数

`%c%` = function(a, b) paste0(a, b) 

对两个或多个字符串按以下方式:

"A_" %c% f 
"A_" %c% f %c% r

如果我想在循环中使用这个对象,我可以使用函数:

`%u%` = function(a, b) eval(parse(text=paste0(a,b))) 

对两个或多个字符串按以下方式:

"A_" %u% f
"A_" %c% f %u% r

请注意,我仅在最后一步中使用了 %u%。

【问题讨论】:

    标签: r for-loop create-table variable-names


    【解决方案1】:

    您可以尝试使用列表:

    l = vector("list", length(files))
    names(l) = paste0("A_", files)
    for(i in seq_along(files))
      l[[i]] = readWorksheetFromFile(paste0(files[i],".xlsx")))
    

    如果您需要将它们作为单独的变量,您可以创建自己的环境并将它们存储在那里:

    myenv = new.env()
    lapply(seq_along(l), function(i) assign(names(l)[i], l[[i]], pos = myenv))
    

    并使用get检索变量:

    vars = ls(pos = myenv)
    get(vars[1], pos = myenv) 
    

    编辑

    所以实际上你只是在寻找像 _&amp; 这样的运算符:

    `%&%` = function(a, b) get(paste0(a, "_", b))
    
    "A" %&% f
    
    A = "A"
    A %&% f
    

    【讨论】:

    • 谢谢。这在特殊情况下可能会有所帮助。但它并没有比我的其他解决方案更短。
    • 该解决方案在我的情况下不起作用,但至少这是一个很好的例子。根据您的想法,我创建了最终解决方案。请参阅我原始帖子的编辑。谢谢你不仅帮助我解决了这个问题,还帮助我了解了如何创建函数。
    【解决方案2】:

    当我必须批量读取许多文件时,我通常会这样做:

    l <- lapply(paste0(files,".xlsx"), readWorksheetFromFile)
    names(l) <- paste0("A_", files)
    

    不需要for 循环。

    l 是一个包含名为data.frames 的列表。使用str(l) 展示结构。

    可以通过 3 种不同的方式访问单个 data.frame

    l[[1]]
    l$A_File1
    l[["A_File1"]]
    

    虚拟数据

    为了使它成为一个可重复的示例,我创建了如下的虚拟数据:

    set.seed(1234)
    readWorksheetFromFile <- function(f) {
      n <- sample.int(5, 1)
      data.frame(a = sample.int(9, n), b = sample(LETTERS, n), 
                 stringsAsFactors = FALSE)
    }
    files <- paste0("File", 1:5)
    

    【讨论】:

      猜你喜欢
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 2020-09-06
      相关资源
      最近更新 更多