0

我正在尝试编写一个函数,该函数可以一次将另一个函数应用于多个 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 可能是导致此问题的原因吗?如果有人能在这个问题上启发我,甚至指出一个简单的解决方案(如果有的话),我会非常高兴。

提前谢谢了。

4

2 回答 2

1

考试让我很忙,这就是我现在才回答的原因。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)
}
于 2013-07-25T17:45:59.637 回答
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 函数的人。-- Greg Snow R-help(2009 年 7 月)

于 2013-07-18T22:47:51.117 回答