dplyr滞后调用中的意外tidy eval行为

dplyr滞后调用中的意外tidy eval行为,r,dplyr,tidyeval,R,Dplyr,Tidyeval,我有一个函数,它接受一个数据框架和几个变量,我希望它使用整洁的评估原则生成一组滞后变量。它的简单形式如下所示: library(dplyr) cor_lags <- function(df, var1, var2) { var1 <- enquo(var1) var2 <- enquo(var2) df %>% select(!!var1, !!var2) %>% mutate(lag1 = lag(!!var2, 1),

我有一个函数,它接受一个数据框架和几个变量,我希望它使用整洁的评估原则生成一组滞后变量。它的简单形式如下所示:

library(dplyr)
cor_lags <- function(df, var1, var2) {
  var1 <- enquo(var1)
  var2 <- enquo(var2)
  df %>% 
    select(!!var1, !!var2) %>% 
    mutate(lag1 = lag(!!var2, 1),
           lag2 = lag(!!var2, 2),
           lag3 = lag(!!var2, 3),
           lag4 = lag(!!var2, 4),
           lag5 = lag(!!var2, 5),
           lag6 = lag(!!var2, 6))
}
是不是有一个原因!!评估人员没有在
延迟
呼叫中工作?他们显然在
select
调用中工作

上述调用的预期行为在实践中应与以下代码类似(有效):

#应为

cor_lags你把准引号语法弄混了。或者

  • enquo
    替换为
    sym
    (或
    rlang::sym
    )以将字符串转换为符号

    cor_lags <- function(df, var1, var2) {
      var1 <- sym(var1);                              # Turn string into symbol
      var2 <- sym(var2);                              # Turn string into symbol
      df %>%
        select(!!var1, !!var2) %>%
        mutate(lag1 = lag(!!var2, 1),
               lag2 = lag(!!var2, 2),
               lag3 = lag(!!var2, 3),
               lag4 = lag(!!var2, 4),
               lag5 = lag(!!var2, 5),
               lag6 = lag(!!var2, 6))
    }
    
    cor_lags(mtcars, "mpg", "disp") %>% head()        # var1, var2 as string
    #   mpg disp lag1 lag2 lag3 lag4 lag5 lag6
    #1 21.0  160   NA   NA   NA   NA   NA   NA
    #2 21.0  160  160   NA   NA   NA   NA   NA
    #3 22.8  108  160  160   NA   NA   NA   NA
    #4 21.4  258  108  160  160   NA   NA   NA
    #5 18.7  360  258  108  160  160   NA   NA
    #6 18.1  225  360  258  108  160  160   NA
    

    • 你把准引号语法弄混了。或者

      • enquo
        替换为
        sym
        (或
        rlang::sym
        )以将字符串转换为符号

        cor_lags <- function(df, var1, var2) {
          var1 <- sym(var1);                              # Turn string into symbol
          var2 <- sym(var2);                              # Turn string into symbol
          df %>%
            select(!!var1, !!var2) %>%
            mutate(lag1 = lag(!!var2, 1),
                   lag2 = lag(!!var2, 2),
                   lag3 = lag(!!var2, 3),
                   lag4 = lag(!!var2, 4),
                   lag5 = lag(!!var2, 5),
                   lag6 = lag(!!var2, 6))
        }
        
        cor_lags(mtcars, "mpg", "disp") %>% head()        # var1, var2 as string
        #   mpg disp lag1 lag2 lag3 lag4 lag5 lag6
        #1 21.0  160   NA   NA   NA   NA   NA   NA
        #2 21.0  160  160   NA   NA   NA   NA   NA
        #3 22.8  108  160  160   NA   NA   NA   NA
        #4 21.4  258  108  160  160   NA   NA   NA
        #5 18.7  360  258  108  160  160   NA   NA
        #6 18.1  225  360  258  108  160  160   NA
        

      我们可以创建一个函数,该函数既可以接受无引号的字符串,也可以接受带引号的字符串

      library(tidyverse)
      library(rlang)
      cor_lags <- function(df, var1, var2) {
      
      
        var1 <- parse_expr(quo_name(enquo(var1)))                           
        var2 <- parse_expr(quo_name(enquo(var2)))   
      
      
        df %>%   
          select(!! var1, !! var2) %>%
          mutate(lag1 = lag(!!var2, 1),
                 lag2 = lag(!!var2, 2),
                 lag3 = lag(!!var2, 3),
                 lag4 = lag(!!var2, 4),
                 lag5 = lag(!!var2, 5),
                 lag6 = lag(!!var2, 6))
      }
      

      我们可以创建一个函数,它既可以接受无引号的字符串,也可以接受带引号的字符串

      library(tidyverse)
      library(rlang)
      cor_lags <- function(df, var1, var2) {
      
      
        var1 <- parse_expr(quo_name(enquo(var1)))                           
        var2 <- parse_expr(quo_name(enquo(var2)))   
      
      
        df %>%   
          select(!! var1, !! var2) %>%
          mutate(lag1 = lag(!!var2, 1),
                 lag2 = lag(!!var2, 2),
                 lag3 = lag(!!var2, 3),
                 lag4 = lag(!!var2, 4),
                 lag5 = lag(!!var2, 5),
                 lag6 = lag(!!var2, 6))
      }
      

      谢谢,
      rlang::sym
      工作正常,但我不明白为什么是enquo+!!在select调用中有效,但在这里的lag调用中无效。谢谢,
      rlang::sym
      确实有效,但我不明白为什么是enquo+!!在select调用中有效,但在此处的lag调用中无效。
      cor_lags <- function(df, var1, var2) {
         var1 <- enquo(var1)                            # Turn expression into quosure
         var2 <- enquo(var2)                            # Turn expression into quosure
         df %>%
           select(!!var1, !!var2) %>%
           mutate(lag1 = lag(!!var2, 1),
                  lag2 = lag(!!var2, 2),
                  lag3 = lag(!!var2, 3),
                  lag4 = lag(!!var2, 4),
                  lag5 = lag(!!var2, 5),
                  lag6 = lag(!!var2, 6))
      }
      cor_lags(mtcars, mpg, disp) %>% head()            # var1, var2 as expressions
      #   mpg disp lag1 lag2 lag3 lag4 lag5 lag6
      #1 21.0  160   NA   NA   NA   NA   NA   NA
      #2 21.0  160  160   NA   NA   NA   NA   NA
      #3 22.8  108  160  160   NA   NA   NA   NA
      #4 21.4  258  108  160  160   NA   NA   NA
      #5 18.7  360  258  108  160  160   NA   NA
      #6 18.1  225  360  258  108  160  160   NA
      
      library(tidyverse)
      library(rlang)
      cor_lags <- function(df, var1, var2) {
      
      
        var1 <- parse_expr(quo_name(enquo(var1)))                           
        var2 <- parse_expr(quo_name(enquo(var2)))   
      
      
        df %>%   
          select(!! var1, !! var2) %>%
          mutate(lag1 = lag(!!var2, 1),
                 lag2 = lag(!!var2, 2),
                 lag3 = lag(!!var2, 3),
                 lag4 = lag(!!var2, 4),
                 lag5 = lag(!!var2, 5),
                 lag6 = lag(!!var2, 6))
      }
      
      cor_lags(mtcars, "mpg", "disp") %>% 
              head() 
      #   mpg disp lag1 lag2 lag3 lag4 lag5 lag6
      #1 21.0  160   NA   NA   NA   NA   NA   NA
      #2 21.0  160  160   NA   NA   NA   NA   NA
      #3 22.8  108  160  160   NA   NA   NA   NA
      #4 21.4  258  108  160  160   NA   NA   NA
      #5 18.7  360  258  108  160  160   NA   NA
      #6 18.1  225  360  258  108  160  160   NA
      
      cor_lags(mtcars, mpg, disp) %>%
               head()    
      #  mpg disp lag1 lag2 lag3 lag4 lag5 lag6
      #1 21.0  160   NA   NA   NA   NA   NA   NA
      #2 21.0  160  160   NA   NA   NA   NA   NA
      #3 22.8  108  160  160   NA   NA   NA   NA
      #4 21.4  258  108  160  160   NA   NA   NA
      #5 18.7  360  258  108  160  160   NA   NA
      #6 18.1  225  360  258  108  160  160   NA