【问题标题】:Passing column name and data frame to custom function in R将列名和数据框传递给R中的自定义函数
【发布时间】:2019-03-28 19:11:54
【问题描述】:

我正在尝试在 R 中编写一个函数:

1) 接收数据框和列名作为参数。 2) 对数据框中的列执行操作。

func <- function(col, df)
{
  col = deparse(substitute(col))
  print(paste("Levels: ", levels(df[[col]])))
}


func(Col1, DF)

func(Col2, DF)

mapply(func, colnames(DF)[1:2], DF)

输出

> func(Col1, DF)
[1] "Levels:  GREEN"  "Levels:  YELLOW"

> func(Col2, DF)
[1] "Levels:  0.1" "Levels:  1"  

> mapply(func, colnames(DF)[1:2], DF)
 Error in `[[.default`(df, col) : subscript out of bounds 

【问题讨论】:

  • 您能否将您的DF 显示为一个可重复的小示例

标签: r dataframe apply sapply mapply


【解决方案1】:

两件事:

  • 在您的函数func 中,您将deparse(substitute(col)) 应用于您期望的对象col 不是字符串。所以它适用于func(Col1, DF)。但是在您的mapply() 调用中,您的参数colnames(...) 是一个字符串,因此会产生错误。使用func('Col1', DF) 获得相同的错误。

  • mapply() 调用中,所有参数都必须是向量或列表。所以你需要使用list(df, df),或者如果你不想复制,去掉你的函数func的参数df

这是一种可行的替代方法:

func <- function(col, df)
{
  print(paste("Levels: ", levels(df[,col])))
}

mapply(FUN = func, colnames(DF)[1:2], list(DF, DF))

【讨论】:

  • 谢谢@demarsylvain。不幸的是,我确实尝试了您建议的代码,但它没有运行。我得到的输出是: mapply 中的错误(FUN = func, colnames(df)[1:2], list(df, df)) :零长度输入不能与非零长度的输入混合
  • mapply(FUN = func, c('Species', 'Species'), list(iris, iris)) 运行没有错误。我们可以提供您的数据集样本吗?
  • &gt; func &lt;- function(col) + { + print(paste("Levels: ", levels(df[,col]))) + } &gt; mapply(FUN = func, c('Species', 'Species'), list(iris, iris)) Error in (function (col) : unused argument (dots[[2]][[1]])
  • 当您在函数中删除参数 df 时,您的 mapply() 调用不正确。此调用使用数据框df,并且此数据框中可能没有名为Species 的列。仅当您始终在同一个数据集上工作时,您才能删除此参数。如果你改变了(就像这个例子中的iris),你需要这个参数。
【解决方案2】:

请查看@demarsylvain 的最后一条评论 - 可能是您这边的复制粘贴错误,您应该这样做:

func <- function(col,df) {
  print(paste("Levels: ", levels(df[,col])))
}

mapply(FUN = func, c('Species', 'Species'), list(iris, iris))

你做到了:

func <- function(col) {
  print(paste("Levels: ", levels(df[,col])))
}

mapply(FUN = func, c('Species', 'Species'), list(iris, iris))

请投票并接受@demarsylvain 的解决方案,它有效

编辑以解决您的评论:

要获得任意列名列表的通用版本,您可以使用此代码,抱歉循环:)

func <- function(col,df) {
  print(paste("Levels: ", levels(df[,col])))
}

cnames = colnames(iris)


i <- 1
l = list()
while(i <= length(cnames)) {
  l[[i]] <- iris
  i <- i + 1
}

mapply(FUN = func, cnames, l)

【讨论】:

  • 谢谢!如果我的数据框有 1000 列并且我想做 mapply,有可能吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
相关资源
最近更新 更多