首页 > 解决方案 > 编写一个函数,其输入是函数中调用的数据框的一列

问题描述

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

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

但我得到同样的错误

标签: rfunctionrstudiolm

解决方案


你真的需要有未引用的列吗?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也会改变内部的对象。赋值运算符通过引用分配任何内容。看这个Q来更彻底的解释。如果您希望更改函数内部“但在外部”的对象并返回一个包含结果对象的列表,您需要首先使用:dListreturn:=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)
}

推荐阅读