【问题标题】:R - Passing a column name to a function to be evaluated in a non standard wayR - 将列名传递给要以非标准方式评估的函数
【发布时间】:2018-02-02 09:24:23
【问题描述】:

我有一个数据框,我想在其中将列名传递给 R in,然后根据该列进行过滤。 我已经尝试阅读一些关于此的教程,它似乎与 R 中的非标准评估有关。

我似乎无法完全理解我阅读过的博客文章中的示例。 为简单起见,我采用了 iris 数据集,我想将一列传递给一个函数,然后该函数将过滤列值大于 1 的数据集。

mydf <- iris

filter_measurements <- function(mydf, measurement){

  mydf <- filter(measurement >= 1)
  mydf

}

mydf %>% 
  filter_measurements(measurement = Petal.Width)

我是否必须在我的函数中添加一些内容,以便 R 知道我想要一列而不是将其用作“Petal.Width”。

我看到 Passing a variable name to a function in R 无法适应我的示例

感谢大家的宝贵时间

【问题讨论】:

  • 您的示例的问题是 dplyr::filter 本身使用非标准评估。
  • deparse(substitute()) 可以在这里提供帮助

标签: r


【解决方案1】:

Programming with dplyr 是一个很好的资源。

mydf <- iris

filter_measurements <- function(mydf, measurement){
  measurement <- enquo(measurement)

  mydf <- filter(mydf, (!!measurement) >= 1)
  mydf

}

mydf %>% 
  filter_measurements(measurement = Petal.Width)

你必须告诉函数,measurement 作为一个裸变量名给出。首先使用enquo 来评估测量参数中给出的内容并将其存储为quosure。然后在测量前面使用!!,filter 函数知道它不必引用这个参数,因为它已经是一个quosure。

替代方案

您也可以将要过滤的列作为字符串传递并使用filter_:

filter_measurements <- function(mydf, measurement){

  mydf <- filter_(mydf, paste0(measurement, " >= 1"))
  mydf

}

mydf %>% 
  filter_measurements(measurement = "Petal.Width")

【讨论】:

  • 嗨@kath,非常感谢您提供这个非常简洁的答案。现在更有意义了。周末愉快
【解决方案2】:

您必须将列名作为列的字符或整数索引传递。此外,行

mydf <- filter(measurement >= 1)

在您的函数中从不声明 什么 正在被过滤,并且会期望“测量”是一个独立的对象,而不是数据框的一部分。 试试这个:

filter_measurements <- function(mydf, measurement)
{
  mydf <- filter(mydf, mydf[,measurement] >= 1)
  mydf
}

iris %>% filter_measurements("Petal.Width")

更复杂的函数调用也可以:

iris %>% filter_measurements(which(names(.)=="Petal.Width"))

【讨论】:

    猜你喜欢
    • 2015-02-17
    • 2017-04-17
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多