编程功能:DPLYR 和 PURRR 中的 NSE
Programming Functions: NSE in DPLYR and PURRR
目前我 运行 在尝试围绕我多次使用的 dplyr und purrr 完成的一些计算包装函数时遇到非标准评估的一些问题。
我已经阅读了有关 NSE 的内容,并且认为我知道我的功能无法正常工作的地方 - 但是,我无法弄清楚这是为什么。
例如,我想围绕以下计算包装一个函数,其中分组变量以及新变量的名称、使用的分类变量和均值的输入变量应该是动态的:
Data <- Data %>%
group_by(WeekBeforeRelease) %>%
mutate(visitors_genreother_instr = map_dbl(Genre_Category, ~ mean(Visitors[Genre_Category != .x]))) %>%
ungroup() %>%
as.data.frame()
将此函数转换为以下内容,使用 NSE here:
Function_Other <- function(ENDOGVAR, VARNAME, GROUP_MOVIE, GROUP_TIME){
ENDOGVAR <- enquo(ENDOGVAR)
VARNAME <- quo_name(enquo(VARNAME))
GROUP_MOVIE <- enquo(GROUP_MOVIE)
GROUP_TIME <- enquo(GROUP_TIME)
Data <<- Data %>%
group_by(!!GROUP_TIME) %>%
mutate(!!VARNAME := map_dbl(!!GROUP_MOVIE, ~mean(!!ENDOGVAR[!!GROUP_MOVIE != .x]))) %>%
ungroup() %>%
as.data.frame()
}
但是,这似乎不能很好地处理均值计算中带括号的子集。如果我将 !!ENDOGVAR 替换为 Visitors,则一切正常且按预期进行。但是,按原样,它会产生以下错误:
Error in NextMethod("[") : object '.x' not found
我很高兴任何帮助我理解这个问题的帮助。
非常感谢!
回旋曲
我们可以将 !!
括在大括号中以避免任何操作优先级,现在应该可以正常工作了
library(tidyverse)
Function_Other <- function(ENDOGVAR, VARNAME, GROUP_MOVIE, GROUP_TIME){
ENDOGVAR <- enquo(ENDOGVAR)
VARNAME <- quo_name(enquo(VARNAME))
GROUP_MOVIE <- enquo(GROUP_MOVIE)
GROUP_TIME <- enquo(GROUP_TIME)
Data %>%
group_by(!!GROUP_TIME) %>%
mutate(!!VARNAME := map_dbl(!!GROUP_MOVIE, ~
mean((!!ENDOGVAR)[(!!GROUP_MOVIE) != .x]))) %>%
ungroup() %>%
as.data.frame()
}
Data <- mtcars
out <- Function_Other(mpg, newcol, am, gear)
head(out, 3)
# mpg cyl disp hp drat wt qsec vs am gear carb newcol
#1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 21.05
#2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 21.05
#3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 21.05
更新
使用 rlang 0.4.0
(使用 dplyr
0.8.2
测试)我们还可以使用 {{...}}
进行替换、引用和取消引用。前面的函数可以写成
Function_OtherN <- function(ENDOGVAR, VARNAME, GROUP_MOVIE, GROUP_TIME){
Data %>%
group_by({{GROUP_TIME}}) %>%
mutate({{VARNAME}} := map_dbl({{GROUP_MOVIE}}, ~
mean({{ENDOGVAR}}[{{GROUP_MOVIE}} != .x]))) %>%
ungroup() %>%
as.data.frame()
}
out1 <- Function_OtherN(mpg, newcol, am, gear)
-检查之前的输出
identical(out1, out)
[1] TRUE
目前我 运行 在尝试围绕我多次使用的 dplyr und purrr 完成的一些计算包装函数时遇到非标准评估的一些问题。
我已经阅读了有关 NSE 的内容,并且认为我知道我的功能无法正常工作的地方 - 但是,我无法弄清楚这是为什么。
例如,我想围绕以下计算包装一个函数,其中分组变量以及新变量的名称、使用的分类变量和均值的输入变量应该是动态的:
Data <- Data %>%
group_by(WeekBeforeRelease) %>%
mutate(visitors_genreother_instr = map_dbl(Genre_Category, ~ mean(Visitors[Genre_Category != .x]))) %>%
ungroup() %>%
as.data.frame()
将此函数转换为以下内容,使用 NSE here:
Function_Other <- function(ENDOGVAR, VARNAME, GROUP_MOVIE, GROUP_TIME){
ENDOGVAR <- enquo(ENDOGVAR)
VARNAME <- quo_name(enquo(VARNAME))
GROUP_MOVIE <- enquo(GROUP_MOVIE)
GROUP_TIME <- enquo(GROUP_TIME)
Data <<- Data %>%
group_by(!!GROUP_TIME) %>%
mutate(!!VARNAME := map_dbl(!!GROUP_MOVIE, ~mean(!!ENDOGVAR[!!GROUP_MOVIE != .x]))) %>%
ungroup() %>%
as.data.frame()
}
但是,这似乎不能很好地处理均值计算中带括号的子集。如果我将 !!ENDOGVAR 替换为 Visitors,则一切正常且按预期进行。但是,按原样,它会产生以下错误:
Error in NextMethod("[") : object '.x' not found
我很高兴任何帮助我理解这个问题的帮助。
非常感谢!
回旋曲
我们可以将 !!
括在大括号中以避免任何操作优先级,现在应该可以正常工作了
library(tidyverse)
Function_Other <- function(ENDOGVAR, VARNAME, GROUP_MOVIE, GROUP_TIME){
ENDOGVAR <- enquo(ENDOGVAR)
VARNAME <- quo_name(enquo(VARNAME))
GROUP_MOVIE <- enquo(GROUP_MOVIE)
GROUP_TIME <- enquo(GROUP_TIME)
Data %>%
group_by(!!GROUP_TIME) %>%
mutate(!!VARNAME := map_dbl(!!GROUP_MOVIE, ~
mean((!!ENDOGVAR)[(!!GROUP_MOVIE) != .x]))) %>%
ungroup() %>%
as.data.frame()
}
Data <- mtcars
out <- Function_Other(mpg, newcol, am, gear)
head(out, 3)
# mpg cyl disp hp drat wt qsec vs am gear carb newcol
#1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 21.05
#2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 21.05
#3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 21.05
更新
使用 rlang 0.4.0
(使用 dplyr
0.8.2
测试)我们还可以使用 {{...}}
进行替换、引用和取消引用。前面的函数可以写成
Function_OtherN <- function(ENDOGVAR, VARNAME, GROUP_MOVIE, GROUP_TIME){
Data %>%
group_by({{GROUP_TIME}}) %>%
mutate({{VARNAME}} := map_dbl({{GROUP_MOVIE}}, ~
mean({{ENDOGVAR}}[{{GROUP_MOVIE}} != .x]))) %>%
ungroup() %>%
as.data.frame()
}
out1 <- Function_OtherN(mpg, newcol, am, gear)
-检查之前的输出
identical(out1, out)
[1] TRUE