我正在尝试编写一个可以同时将多个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调用函数时的原因是什么?如果有人能在这个问题上给我启发,或者甚至指出一个简单的解决方案(如果有的话),我会很高兴。
非常感谢提前。
答案 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)
我还考虑了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)
}