R:创建带有省略号参数的函数时的词法范围问题
R: Lexical Scoping issue when creating a function with ellipsis argument
我在 R 中制作了很多频率 tables 并且正在编写我自己的快速频率 table (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(),则会产生错误 "Error in table(...) : 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() 中那样)?
您可以使用 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
我在 R 中制作了很多频率 tables 并且正在编写我自己的快速频率 table (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(),则会产生错误 "Error in table(...) : 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() 中那样)?
您可以使用 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