R:使用省略号参数创建函数时的词法范围问题

时间:2019-03-01 18:30:39

标签: r function frequency ellipsis lexical-scope

我在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(),则会生成错误“表(...)中的错误:未找到对象'cyl'”。作为解决方法,我编写了以下函数,虽然可以产生预期的结果,但是需要稍微不同的输入。

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())?

1 个答案:

答案 0 :(得分:1)

您可以使用rlang中的等价捕获...中的参数,然后取消引号将它们拼接成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