我正在尝试编写一个函数,该函数具有作为输入参数的一列数据框,这些列在函数中被迭代调用。
示例如下所示: 编写一个称为iter的函数,该函数有2个输入: 1)数据框列表 2)df1和df2都包含的列的名称
iter <- function (dflist, columnname) {
for (df in dflist){
df[,bla:=cut(columnname, etc)]
lm(...data=df)
etc
}
}
例如:
dflist = list(df1,df2)
df1和df2都包含名为col1的列
我想编写一个函数,这样当我键入
iter(dflist,col1)
我得到df[,bla:=cut(col1, etc)]
但是,每当我现在运行它时,都会出现此错误-"object 'col1' not found.
我尝试将col1作为列表传递并使用get(columnname),但无济于事:
iter <- function (dflist, columnname) {
for (df in dflist){
df[,bla:=cut(get(columnname), etc)]
lm(...data=df)
etc
}
}
iter(dflist,'col1')
但是我得到同样的错误
答案 0 :(得分:0)
您是否真的需要未引用的列?我发现动态更改具有columname
参数作为单个character
字符串对象的列要容易得多。您可以使用as.symbol()
–或as.name()
–创建一个对象(函数中的sym
),该对象稍后将使您称该对象为R对象,而不是其值,分配给columname
的任何内容。
然后,您可以按照常规eval()
语法使用data.table
在其环境中评估sym
对象。
library(data.table)
dList <- list(
mtcars,
mtcars
)
dList <- lapply(dList, function(x) copy(as.data.table(x)))
iter <- function (dflist, columnname) {
new_var <- paste0(columnname, "_sq")
sym <- as.symbol(columnname)
for (df in dflist){
df[,(new_var):= eval(sym)^2]
}
}
iter(dList, "mpg")
结果...
> head(dList[[2]], 1)
mpg cyl disp hp drat wt qsec vs am gear carb mpg_sq
1: 21 6 160 110 3.9 2.62 16.46 0 1 4 4 441
请记住,即使您未在函数中指定iter
,dList
也会改变return
中的对象。赋值运算符:=
通过引用分配任何内容。请参阅此Q以获得更详尽的说明。如果要在函数“内外”中更改对象并返回包含结果对象的列表,则需要首先使用data.table::copy
:
iter <- function (dflist, columnname) {
new_var <- paste0(columnname, "_sq")
res <- vector("list", length(dflist))
sym <- as.symbol(columnname)
for (i in seq_along(res)){
dt <- copy(dflist[[i]])
res[[i]] <- dt[,(new_var):= eval(sym)^2]
}
return(res)
}