使用输入作为函数中调用的数据框的列来编写函数

时间:2019-09-09 18:19:11

标签: r function rstudio lm

我正在尝试编写一个函数,该函数具有作为输入参数的一列数据框,这些列在函数中被迭代调用。

示例如下所示: 编写一个称为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')

但是我得到同样的错误

1 个答案:

答案 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

请记住,即使您未在函数中指定iterdList也会改变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)
}