简体   繁体   English

编程功能:DPLYR和PURRR中的NSE

[英]Programming Functions: NSE in DPLYR and PURRR

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. 当前,当我尝试将函数包装在我多次使用的dplyr und purrr进行的一些计算周围时,我遇到了非标准评估的一些问题。

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. 我已经阅读了有关NSE的文章,也认为我知道我的功能无法正常工作的地方-但是,我不知道为什么会这样。

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 : 果然这个功能为以下,使用NSE描述在这里

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. 如果我用Visitors代替!! ENDOGVAR,一切都会按预期进行。 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

Update 更新资料

With rlang 0.4.0 (tested with dplyr 0.8.2 ) we can also use {{...}} for substitute, quote, and unquote. 使用rlang 0.4.0 (经dplyr 0.8.2测试),我们还可以使用{{...}}来替代,引用和取消引用。 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM