currently I am running into some problems with Non-Standard Evaluation when trying to wrap a function around some calculations done with dplyr und purrr that I use on multiple occasions.
I have read about NSE and also think I know the point where my function does not work properly - however, I could not figure out why this is.
Examplarily, I want to wrap a function around the following calculations, where the grouping variable as well as the name of the new variable, the utilized categorization variable and the input variable for the mean should be dynamic:
Data <- Data %>%
group_by(WeekBeforeRelease) %>%
mutate(visitors_genreother_instr = map_dbl(Genre_Category, ~ mean(Visitors[Genre_Category != .x]))) %>%
ungroup() %>%
as.data.frame()
Which turns this function into the following, using NSE as described 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()
}
However, this does not seem to handle the subsetting with brackets in the mean calculation well. If I subtitute the !!ENDOGVAR with Visitors, everything works fine and as intended. However, as is, it produces the following error:
Error in NextMethod("[") : object '.x' not found
I am happy about any help that points me towards understanding this problem.
Thanks a lot in advance!
rondo
We can wrap the !!
in braces to avoid any precedence of operations and should now work fine
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
With rlang 0.4.0
(tested with dplyr
0.8.2
) we can also use {{...}}
for substitute, quote, and unquote. The previous function can be written as
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)
-checking with previous output
identical(out1, out)
[1] TRUE
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.