【问题标题】:r error in rep(value, length.out = n) : attempt to replicate an object of type 'closure' [duplicate]rep(value, length.out = n) 中的 r 错误:尝试复制“closure”类型的对象 [重复]
【发布时间】:2013-07-17 22:05:09
【问题描述】:

我正在尝试编写一个函数,该函数可以一次将另一个函数应用于多个 data.frames。 data.frames 命名为 DATA_1、DATA_2 等,变量“actioncol”用于指示必须更改的列。到目前为止,这是我的代码:

gsubFUN <- function(name, actioncol, ...){
  df.vec <- ls(pattern =  paste("name", "*", sep="_"), envir=.GlobalEnv)
  for(ii in 1:length(df.vec)){
  DATA <- get(df.vec[ii])
  DATA[,actioncol] <- gsub(pattern.vec[ii], replace.vec[ii], DATA[,actioncol])
  assign(paste(name, ii, sep = "_"),DATA, envir = .GlobalEnv)    
  }
}

我知道我的代码可能很混乱,但它确实有效。由于我希望外部函数也可以在 data.frames 上应用其他函数(不仅仅是 gsub),因此我尝试用变量替换它:

multiDfFUN <- function(name, actioncol, FUN, ...){
  df.vec <- ls(pattern =  paste(name, "*", sep="_"), envir=.GlobalEnv)
  for(ii in 1:length(df.vec)){
  DATA <- get(df.vec[ii])
  DATA[,actioncol] <- match.fun(FUN)
  assign(paste(name, ii, sep = "_"),DATA, envir = .GlobalEnv)    
  }
}

multiDfFUN(name="audi", actioncol="color", FUN=gsub, pattern=pattern.vec[ii],
       replacement=replace.vec[ii], x=DATA[,actioncol])

然而,这会返回一条错误消息:

error in rep(value, length.out = n) : 
   attempt to replicate an object of type 'closure'

我什至不明白这是什么意思。搜索网络也无济于事。调用函数时的参数模式、替换和 x 可能是导致此问题的原因吗?如果有人能在这个问题上启发我,甚至指出一个简单的解决方案(如果有的话),我会非常高兴。

非常感谢。

【问题讨论】:

  • 你怎么能说搜索没有帮助?我刚刚通过搜索错误消息找到了this
  • 我之前也读过那篇文章,没有为我澄清,抱歉。
  • 你的印象是&lt;- match.fun(FUN)DATA[,actioncol]上调用函数FUN吗?
  • 是的,我就是这么想的。猜错了吗?
  • 大错特错。也许您可以简单地将gsub(...) 替换为FUN(...)。但我会在这里留下我的标准建议,即这个功能非常混乱。从您的词典中删除getassign;根据需要将参数传递给函数并返回值。不要跨环境获取您需要的对象,然后不要分配到全局环境中。从风格上讲,这很糟糕,而且只会造成比其价值更多的问题。

标签: r function


【解决方案1】:

这一行:

DATA[,actioncol] <- match.fun(FUN)

... 正在尝试将函数(不是函数名称)分配给数据框中的项目。那不会成功。然后你写:

assign(paste(name, ii, sep = "_"),DATA, envir = .GlobalEnv)    

这种努力与 R 的首选编程风格非常相反。从函数体内分配给 GlobalEnv 只能由知道该错误消息含义的人尝试。 match.fun 返回一个函数,所以我想你会做这样的事情:

 DATA[,actioncol] <-  match.fun(FUN)( DATA[,actioncol] )
 return(DATA)

然后这样称呼它:

DATAnew <- multiDfFUN(name="audi", actioncol="color", FUN=gsub, 
                      pattern=pattern.vec[ii],
                      replacement=replace.vec[ii], x=DATA[,actioncol])

由于我们没有可使用的示例数据,我将把它作为未经测试的猜测。

证明中添加的注释:

 fortunes::fortune("understand why")

唯一应该使用assign函数的人是那些完全理解的人 为什么你永远不应该使用assign函数。 ——格雷格·斯诺 R 帮助(2009 年 7 月)

【讨论】:

    【解决方案2】:

    考试让我很忙,这就是我现在才回答的原因。 DWin 的建议实际上帮助我使该功能按预期工作。

    我还考虑了您对attach的所有警告。但如前所述,我为一个明确要求我使用它的任务编写了这段代码。所以这就是我最终的结果:

    MultiDfFUN <- function(df.vec, col.name, col.new="new", df.name, 
                           FUN, overwrite=F, ...){
     df.list <- list(NULL)
     for(ii in 1:length(df.vec)){
        DATA <- get(df.vec[ii])
        DATA[,col.new] <- FUN(DATA[,col.name],...)
    
        if(overwrite == TRUE){
          assign(paste(df.name, ii, sep = "_"),DATA, envir = .GlobalEnv)
        }else{
          df.list[[ii]] <- DATA[,col.new]
        }
      }
      if(overwrite == FALSE) return(df.list)
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-24
      • 2021-06-29
      • 2019-12-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 1970-01-01
      • 1970-01-01
      • 2019-07-16
      相关资源
      最近更新 更多