【问题标题】:Inner_join on NSENSE 上的 Inner_join
【发布时间】:2022-01-06 21:24:27
【问题描述】:

我想编写一个连接两个 tibble 的函数,第二个 tibble 的连接列在函数的 args 中指定。

我有

df1 <- tibble(NUMBER = c(1,4))
df2 <- tibble(ORDER = 1:5,
              DISORDER = 5:1,
              WORD = c("The", "quick", "brown", "fox", "jumped"))

我想要

chozer(df1, df2, ORDER)
# to yield
tibble(NUMBER = c(1,4),
       DISORDER = c(5,2),
       WORD = c("The", "fox"))
# and
chozer(df1, df2, DISORDER)
# to yield
tibble(NUMBER = c(5,2),
       DISORDER = c(1,4),
       WORD = c("jumped", "quick"))

我已经尝试了几种变体

chozer <- function(df1, df2, ColName){
  aCol = enquo(ColName)
  inner_join(df1, df2, by = c(NUMBER = aCol))
}
# but they all gave errors.

我查看了 Hadley Wickham 的 Advanced R,但没有发现在连接的 by 子句中使用 NSE(非标准评估)的示例。

你知道吗?

【问题讨论】:

    标签: r tidyverse inner-join nse


    【解决方案1】:

    你可以使用deparse(substitute(ColName)):

    chozer <- function(df1, df2, ColName){
        inner_join(df1, df2, by = c(NUMBER = deparse(substitute(ColName))))
      }
    
    chozer(df1, df2, DISORDER)
    # A tibble: 2 x 3
      NUMBER ORDER WORD  
       <dbl> <int> <chr> 
    1      1     5 jumped
    2      4     2 quick 
    
    chozer(df1, df2, ORDER)
    # A tibble: 2 x 3
      NUMBER DISORDER WORD 
       <dbl>    <int> <chr>
    1      1        5 The  
    2      4        2 fox  
    

    【讨论】:

      【解决方案2】:

      使用rlang::ensym 和rlang::as_string 你可以这样做:

      library(dplyr)
      
      df1 <- tibble(NUMBER = c(1,4))
      df2 <- tibble(ORDER = 1:5,
                    DISORDER = 5:1,
                    WORD = c("The", "quick", "brown", "fox", "jumped"))
      
      chozer <- function(df1, df2, ColName){
        aCol = ensym(ColName)
        inner_join(df1, df2, by = c(NUMBER = rlang::as_string(aCol)))
      }
      
      chozer(df1, df2, ORDER)
      #> # A tibble: 2 × 3
      #>   NUMBER DISORDER WORD 
      #>    <dbl>    <int> <chr>
      #> 1      1        5 The  
      #> 2      4        2 fox
      
      chozer(df1, df2, DISORDER)
      #> # A tibble: 2 × 3
      #>   NUMBER ORDER WORD  
      #>    <dbl> <int> <chr> 
      #> 1      1     5 jumped
      #> 2      4     2 quick
      

      见https://adv-r.hadley.nz/quasiquotation.html#quasi-motivation

      【讨论】:

        【解决方案3】:

        一个选项也是rename 并通过公共列加入

        library(dplyr)
        chozer <- function(df1, df2, ColName){
         
            df2 %>%
              rename(NUMBER := {{ColName}}) %>%  
              inner_join(df1)
         }
        

        -测试

        > chozer(df1, df2, ORDER)
        Joining, by = "NUMBER"
        # A tibble: 2 × 3
          NUMBER DISORDER WORD 
           <dbl>    <int> <chr>
        1      1        5 The  
        2      4        2 fox  
        > chozer(df1, df2, DISORDER)
        Joining, by = "NUMBER"
        # A tibble: 2 × 3
          ORDER NUMBER WORD  
          <int>  <dbl> <chr> 
        1     2      4 quick 
        2     5      1 jumped
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-08-11
          • 1970-01-01
          • 2014-11-22
          • 1970-01-01
          • 2018-12-29
          • 2019-11-20
          • 2018-04-12
          • 1970-01-01
          相关资源
          最近更新 更多