gpt4 book ai didi

r - 创建一个函数,并将参数传递给 dplyr::filter 解决 nse 的最佳方法是什么?

转载 作者:行者123 更新时间:2023-12-02 14:10:56 39 4
gpt4 key购买 nike

非标准评估在以下情况下确实很方便使用 dplyr 的动词。但使用这些时可能会出现问题带功能参数的动词。例如,假设我想创建一个函数给出给定物种的行数。

# Load packages and prepare data
library(dplyr)
library(lazyeval)
# I prefer lowercase column names
names(iris) <- tolower(names(iris))
# Number of rows for all species
nrow(iris)
# [1] 150

示例不起作用

此函数无法按预期工作,因为物种在 iris 数据框的上下文中解释而不是在上下文中进行解释函数参数:

nrowspecies0 <- function(dtf, species){
dtf %>%
filter(species == species) %>%
nrow()
}
nrowspecies0(iris, species = "versicolor")
# [1] 150

3个实现示例

为了解决非标准评估问题,我通常在参数后面添加下划线:

nrowspecies1 <- function(dtf, species_){
dtf %>%
filter(species == species_) %>%
nrow()
}

nrowspecies1(iris, species_ = "versicolor")
# [1] 50
# Because of function name completion the argument
# species works too
nrowspecies1(iris, species = "versicolor")
# [1] 50

不太令人满意因为它将函数参数的名称更改为一些不太用户友好的东西。或者它依赖于自动完成恐怕这不是编程的好习惯。为了保留一个漂亮的参数名称,我可以做:

nrowspecies2 <- function(dtf, species){
species_ <- species
dtf %>%
filter(species == species_) %>%
nrow()
}
nrowspecies2(iris, species = "versicolor")
# [1] 50

解决非标准评估的另一种方法基于this answerinterp() 在上下文中解释 species功能环境:

nrowspecies3 <- function(dtf, species){
dtf %>%
filter_(interp(~species == with_species,
with_species = species)) %>%
nrow()
}
nrowspecies3(iris, species = "versicolor")
# [1] 50

考虑到上面的3个函数,实现此过滤功能的首选(最稳健的)方法是什么?还有其他方法吗?

最佳答案

@eddi 的回答对于这里发生的情况是正确的。我正在编写另一个答案,解决如何使用 dplyr 动词编写函数的更大要求。您会注意到,最终,它使用类似 nrowspecies2 的东西来避免 species ==species 同义反复。

编写一个可与​​ NSE 一起使用的包装 dplyr 动词的函数,请编写两个函数:

首先使用 lazyeval 编写一个需要带引号的输入的版本dplyr 动词的 SE 版本。所以在这种情况下,filter_

nrowspecies_robust_ <- function(data, species){ 
species_ <- lazyeval::as.lazy(species)
condition <- ~ species == species_ # *
tmp <- dplyr::filter_(data, condition) # **
nrow(tmp)
}
nrowspecies_robust_(iris, ~versicolor)

第二次制作一个使用 NSE 的版本:

nrowspecies_robust <- function(data, species) { 
species <- lazyeval::lazy(species)
nrowspecies_robust_(data, species)
}
nrowspecies_robust(iris, versicolor)

* = 如果您想做更复杂的事情,您可能需要在此处使用 lazyeval::interp,如下面链接的提示所示

** = 另外,如果您需要更改输出名称,请参阅 .dots 参数

关于r - 创建一个函数,并将参数传递给 dplyr::filter 解决 nse 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36647468/

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