【问题标题】:R: Lexical Scoping issue when creating a function with ellipsis argumentR:创建带有省略号参数的函数时的词法范围问题
【发布时间】:2019-03-01 18:30:38
【问题描述】:

我在 R 中制作了很多频率表,并且正在编写自己的快速频率表 (qft) 函数时遇到了我认为是词法范围问题的问题。这是我的功能版本不起作用

library("tidyverse")

data(mtcars)

qft_bad<-function(data,...){
  ft<-data.frame(with(data, table(...)))
  ft<-ft[ft$Freq!=0,]
  return(ft)
}

tst_bad<-qft_bad(mtcars,cyl,gear)

您会注意到,如果您尝试运行 qft_bad(),则会产生错误“表中的错误 (...) : object 'cyl' not found”。作为一种解决方法,我编写了以下函数,它确实产生了预期的结果,但需要稍微不同的输入。

qft_good<-function(data,...){
      nmes<-c(...)
      vars<-dplyr::select(data,...)
      ft<-data.frame(table(vars))
      ft<-ft[ft$Freq!=0,]
      colnames(ft)[1:length(nmes)]<-nmes
      return(ft)
}

tst_good<-qft_good(mtcars,"cyl","gear")

我猜 qft_bad() 不起作用,因为 R 试图评估输入数据集之外的参数,但我有点不清楚这个问题的细节(是否存在一些问题with() 函数?)。

由于 qft_good() 对我的目的来说足够好,我主要是为了我自己的 R 启蒙而问这个问题。谁能更好地解释我的 qft_bad() 函数中发生了什么,或者创建一个不需要您在引号中列出变量名称的 qft 函数版本(正如您必须在 qft_good())?

【问题讨论】:

    标签: r function frequency ellipsis lexical-scope


    【解决方案1】:

    您可以使用 rlang 中的 quosures 来捕获 ... 中的参数,然后将它们取消引用并拼接到 select 调用中:

    library(tidyverse)
    library(rlang)
    
    qft <- function(data, ...){
      args <- enquos(...)
      vars <- select(data, !!!args)
      ft <- data.frame(table(vars))
      ft[ft$Freq != 0, ]
    }
    
    qft(mtcars, cyl, gear)
    #  cyl gear Freq
    #1   4    3    1
    #2   6    3    2
    #3   8    3   12
    #4   4    4    8
    #5   6    4    4
    #7   4    5    2
    #8   6    5    1
    #9   8    5    2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-28
      • 1970-01-01
      • 2013-06-27
      • 2018-01-05
      • 2019-09-01
      • 2019-02-01
      • 1970-01-01
      相关资源
      最近更新 更多