rep中的错误(value,length.out = n):尝试复制'closure'类型的对象

时间:2013-07-18 19:25:19

标签: r function

我正在尝试编写一个可以同时将多个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'

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

非常感谢提前。

2 个答案:

答案 0 :(得分:0)

这一行:

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函数。       - 格雷格雪         R-help(2009年7月)

答案 1 :(得分:0)

考试让我很忙,这就是为什么我现在才回答。 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)
}