代码之家  ›  专栏  ›  技术社区  ›  Dave Rosenman

创建dplyr函数,该函数可以判断变量输入是字符串还是符号

  •  3
  • Dave Rosenman  · 技术社区  · 7 年前

    我一直在研究 "Programming with dplyr" vignette是因为我想创建使用dplyr函数的函数。我想使用我在闪亮的应用程序和交互式r工作中所做的功能。为了在shiny中使用,我希望这些函数采用字符串参数,并使用sym函数将它们转换为符号。为了在交互会话中使用,我希望这些函数具有不必使用字符串的选项。所以我所做的函数需要一种方法来判断某些参数是否是字符串。

    我想出了一个办法。我只是好奇是否有更好和/或更优雅的方法来做这件事。

    我做了一个简单的函数“我的总结”,作为一个例子。它是功能“My_Summary”的另一个版本。它使用trycatch检查group var参数是否为字符串。

    library(dplyr)
    df <- data.frame(g1 = c(1, 1, 2, 2, 2),
      g2 = c(1, 2, 1, 2, 1),
      a = c(1, 5, 4, 3, 2),
      b = c(3, 1, 2, 5, 4))
    
    # df:
    
    #  g1 g2 a b
    #  1  1 1 3
    #  1  2 5 1
    #  2  1 4 2
    #  2  2 3 5
    #  2  1 2 4
    
    my_summarise <- function(df, group_var) {
    
      is_string <- tryCatch(sym(group_var), error = function(group_var) group_var)
    
      if ("error" %in% class(is_string)) { 
        group_var <- enquo(group_var)      
      } else {
        group_var <- sym(group_var)   
      }
    
      df %>% group_by(!! group_var) %>% 
        summarise(a = mean(a))
    }
    
    my_summarise(df, g1)
    # g1     a
    # 1     3
    # 2     3
    
    my_summarise(df, "g1")
    # g1     a
    # 1     3
    # 2     3
    

    编辑: 奥尼安布的回答很完美。我只是把它调整为使用一些rlang函数,而不是它们的基等价函数。

    my_summarise <- function(df, group_var) {
    
      group_var <- enexpr(group_var)
    
      if(!is_symbol(group_var)) group_var <- sym(group_var) # instead of is.name and as.name you can use is.symbol and as.symbol or a mixture. 
    
      group_var <- enquo(group_var)      
    
      df %>% group_by(!! group_var) %>% 
        summarise(a = mean(a))
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Onyambu    7 年前
    my_summarise <- function(df, group_var) {
    
      group_var <- substitute(group_var)
    
     if(!is.name(group_var)) group_var <- as.name(group_var) # instead of is.name and as.name you can use is.symbol and as.symbol or a mixture. 
    
      group_var <- enquo(group_var)      
    
      df %>% group_by(!! group_var) %>% 
        summarise(a = mean(a))
    }
    

    你也可以忽略 if 条件合计:

    my_summarise <- function(df, group_var) {
    
    group_var<- as.name(substitute(group_var))
    
      group_var <- enquo(group_var)      
    
      df %>% group_by(!! group_var) %>% 
        summarise(a = mean(a))
    }
    
        2
  •  3
  •   akrun    7 年前

    我们可以这样做 parse_expr

    my_summarise <- function(df, group_var) {    
    
    
      group_var <- parse_expr(quo_name(enquo(group_var)))   
    
      df %>%
         group_by(!! group_var) %>% 
         summarise(a = mean(a))
    }
    

    -检查

    my_summarise(df, g1)
    # A tibble: 2 x 2
    #     g1     a
    #  <dbl> <dbl>
    #1     1     3
    #2     2     3
    
    my_summarise(df, 'g1')
    # A tibble: 2 x 2
    #     g1     a
    #  <dbl> <dbl>
    #1     1     3
    #2     2     3