gpt4 book ai didi

r - 使用 tidy 评估选择命名的 [list] 元素

转载 作者:行者123 更新时间:2023-12-01 08:08:00 28 4
gpt4 key购买 nike

我试图围绕非标准评估进行思考,因为它在 rlang 中得到了解释。包裹。考虑到这个目标,我的问题是:

How do I write a dplyr::select.list() function that is consistent with tidy evaluation principles?



这是我目前如何围绕 dplyr::select() 编写包装器的示例:
select_wrapper <- function(x, ...) {
vars <- rlang::quos(...)
dplyr::select(x, !!!vars)
}

这适用于数据框,例如,
> select_wrapper(mtcars, cyl, mpg)
> ## cyl mpg
> ## Mazda RX4 6 21.0
> ## Mazda RX4 Wag 6 21.0
> ## Datsun 710 4 22.8
> ## Hornet 4 Drive 6 21.4
> ## Hornet Sportabout 8 18.7
> ## Valiant 6 18.1

但不在列表中:
attr(mtcars, "test") <- "asdf"
mtcars_list <- attributes(mtcars)
select_wrapper(mtcars_list, row.names, test)
> ## 1: c("mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", "gear", "carb")
> ## 2: c("Mazda RX4", "Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", "Hornet Sportabout", "Valiant", "Duster 360", "Merc 240D", "Merc 230", "Merc 280", "Merc 280C", "Merc 450SE", "Merc 450SL", "Merc 450SLC", "Cadillac Fleetwood", "Lincoln Continental", "Chrysler Imperial", "Fiat 128", "Honda Civic", "Toyota Corolla", "Toyota Corona", "Dodge Challenger", "AMC Javelin", "Camaro Z28", "Pontiac Firebird", "Fiat X1-9", "Porsche 914-2", "Lotus Europa", "Ford Pantera L", "Ferrari Dino", "Maserati Bora", "Volvo 142E")
> ## 3: data.frame
> ## 4: asdf
> ## Selection:

老实说,我不确定上面的输出中发生了什么……它返回一个交互式提示,要求我选择我想要的元素。这不是很理想,imo。

无论如何,我想完成的是 select.list()返回我通过非标准评估选择的命名元素列表的函数。这是我的解决方案,但感觉太hacky了:
listdf <- function(x) {
as.data.frame(lapply(x, function(x) I(list(x))))
}
dflist <- function(x) {
x <- lapply(x, unlist, recursive = FALSE)
lapply(x, unclass)
}
select.list <- function(x, ...) {
dots <- rlang::quos(...)
if (length(dots) == 0L) return(list())
x <- listdf(x)
dflist(dplyr::select(x, !!!dots))
}

library(dplyr)
attr(mtcars, "test") <- "asdf"

select(attributes(mtcars), test, row.names)

有没有更干净、更整洁的评估一致的方法来做到这一点?

最佳答案

您可以使用 tidyselect 来实现 select() 的后端:

select2 <- function(.x, ...) {
vars <- rlang::names2(.x)
vars <- tidyselect::vars_select(vars, ...)
.x[vars]
}

x <- list(a = 1, b = 2)
select2(x, dplyr::starts_with("a"))

请注意,当您不拥有泛型(例如 select() 由 dplyr 拥有)或类(例如来自 R 核心的 list)时,实现 S3 方法是不好的做法。

关于r - 使用 tidy 评估选择命名的 [list] 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48690805/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com