0

我在下面的 SO 上找到了这个代码行,它在函数之外起到了一个魅力,用于识别数据帧列表并使用 rbind 加入它们。

    mylist<-ls(pattern='leg_')
    mleg <- do.call(rbind, lapply(mylist, get))

但是当我将它包含在一个循环中时,我收到一条错误消息。我已尝试在功能的各个步骤以及这些工作中进行故障排除,但我可能会遗漏导致此错误的某些内容。

            for(i in 1:(length(blg_idx))){
                assign(paste(deparse(substitute(leg_)),i,sep=''),l_merge(get(paste(deparse(substitute(blg)),i,sep='')),get(paste(deparse(substitute(bsg)),i,sep=''))))
            }

            mylist<-ls(pattern='leg_')

            #return(mylist) # this returns a good list of dataframes

            #mlegleg <- rbind(leg_1,leg_2) # this works 

            mleg <- do.call(rbind, lapply(mylist, get))

            return(mleg)
            } #end function read_leg

            Error in FUN(c("leg_1", "leg_2")[[1L]], ...) : 
              object 'leg_1' not found

当我从函数返回 mylist 时,它能够识别所有数据帧并列出它们。当我选择在调试中返回这些数据帧时,该函数能够返回 leg_1 或 leg_2 数据帧。

            [1] "leg_1" "leg_2"

有什么帮助吗?

更新

我找到了另一个实现我需要的方法,但我确信它效率低下,尽管我的数据框列表最多为 4

            for(i in 1:(length(blg_idx))){
                assign(paste(deparse(substitute(leg_)),i,sep=''),l_merge(get(paste(deparse(substitute(blg)),i,sep='')),get(paste(deparse(substitute(bsg)),i,sep=''))))
            }

            mylist<-ls(pattern='leg_')

            #return(mylist)
            #mlegleg <- rbind(leg_1,leg_2) # this works 
            # mleg <- do.call(rbind, lapply(mylist, get))

            mleg <- leg_1

            for(i in 2:(length(blg_idx))){
                mleg <- rbind(leg,get(paste(deparse(substitute(leg_)),i,sep='')))
            }   

            return(mleg)
            } #end read_leg

更新 2

这是我面临的问题的可重现示例。由于某种原因,do.call & get 无法处理为函数内生成的数据帧生成的 mylist 参数。

    read_date <- function(x){
    pur_1 <- data.frame(sku=859, X = sample(1:10),Y = sample(c("yes", "no"), 10, replace = TRUE))
    pur_2 <- data.frame(sku=859, X = sample(11:20),Y = sample(c("yes", "no","na"), 10, replace = TRUE))

    mylist<-ls(pattern='pur_')

    pur_final <- do.call(rbind, lapply(mylist, get))
    #fancier version that I want to achieve is below
    #assign(paste('pur_',eval(pur_1$sku[1]),sep=''),do.call(rbind, lapply(mylist, get)))
    return(pur_final)
}

read_date()

错误信息是

FUN(c("pur_1", "pur_2")[[1L]], ...) 中的 read_date() 错误:找不到对象 'pur_1'

更新 3 我对这篇文章的非常规管理感到抱歉,但我会在下一篇文章中做得更好。

这是我偶然发现的对我有用的东西,但有一个例外。

pur_final <- do.call(rbind, mget(paste0("pur_", 1:2),envir = as.environment(-1)))

但下一个不太大的问题是抑制添加到数据框中的 row.names。在此上下文中禁止显示 row.names 的任何建议。

    >   read_date()
             sku  X   Y
    pur_1.1  859  8 yes
    pur_1.2  859  4  no
    pur_1.3  859  3 yes
    ....
    pur_2.8  859 14  na
    pur_2.9  859 13  na
    pur_2.10 859 19  no
    >  
4

3 回答 3

2

您没有可重现的示例来测试此解决方案,但请查看帮助页面get并尝试以下操作:

mleg <- do.call(rbind, lapply(mylist, get, envir = globalenv() ))
于 2014-08-14T21:10:57.340 回答
0

一个迟到的回应,但我刚刚遇到了与更新 2发布类似的问题,其中“找不到对象 'pur_1' ”。

如果您有未知数量的以“pur_”开头的数据帧时要在函数中使用以下内容,例如:

mylist <- ls(pattern='pur_')
mleg <- do.call(rbind, lapply(mylist, get))

然后你需要在函数中指向正确的环境:

mylist <- ls(pattern='pur_')
mleg <- do.call(rbind, lapply(mylist, get, env=environment()))
于 2019-04-10T23:43:10.970 回答
0

上面的答案包含了您问题的关键:envir = globalenv() 我花了一段时间才意识到 R 将为每个函数创建一个私有环境。在该私有环境中,您的其他变量不存在。也就是说,除非您告诉您的函数通过使用envir参数来查看全局环境。

这是一个函数,它应该将字符串作为输入,然后识别全局环境中的所有变量(例如数据框),这些变量在其名称中包含该文本字符串。然后它将尝试绑定这些变量(数据框)。

如果所有变量都是具有相同列名的数据框,那么它应该返回一个绑定的数据框。myBindedDF <- mergeCompatibleTables("mypattern")

bindCompatibleTables <- function(x){
  if(is.character(x)){
  mylist <-   grep(x, ls(pos = 1), value=T)
  mergedDF <- do.call(rbind,  mget(mylist,envir = as.environment(1)))

  return(bindedDF)
  } else {
    stop("Input is not a character string")
  }
}
于 2018-03-22T01:08:53.687 回答