代码之家  ›  专栏  ›  技术社区  ›  arnyeinstein

在mutate with paste中使用带有字符串的向量

  •  4
  • arnyeinstein  · 技术社区  · 7 月前

    我试图用“粘贴”在tibble中构建一个ID,并用列名作为字符串构建一个向量:

    library(tidyverse)
    
    df <- tribble(
      ~PERIOD, ~CODE, ~VALUE,
      1995, "A", 10,
      1996, "B", 20
    )
    df
    
    mygroup <- c("PERIOD", "CODE")
    

    我希望得到这个结果

    # A tibble: 2 x 4
      PERIOD CODE  VALUE ID    
       <dbl> <chr> <dbl> <chr> 
    1   1995 A        10 1995_A
    2   1996 B        20 1996_B
    

    当然,以下代码并不能满足我的要求

    df %>% 
      mutate(ID = paste(mygroup, collapse = "_"))
    

    因为它生产

      PERIOD CODE  VALUE ID         
       <dbl> <chr> <dbl> <chr>      
    1   1995 A        10 PERIOD_CODE
    2   1996 B        20 PERIOD_CODE
    

    我试过了!!还有花括号,但什么都没用。

    5 回复  |  直到 7 月前
        1
  •  4
  •   s_baldur    7 月前

    使用base R。代码简洁易用,但如果 mygroup 很长。使用 do.call() 相反。

    df$ID <- Reduce(\(x, y) paste(x, y, sep = "_"), df[mygroup])
    
    #   PERIOD CODE  VALUE ID    
    #    <dbl> <chr> <dbl> <chr> 
    # 1   1995 A        10 1995_A
    # 2   1996 B        20 1996_B
    

    另一个简洁但低效的解决方案:

    df$ID <- apply(df[mygroup], 1, paste, collapse = "_")
    
        2
  •  3
  •   ThomasIsCoding    7 月前

    你可以试试

    df %>%
      mutate(ID = do.call(paste, c(.[mygroup], sep = "_")))
    

    df %>%
      mutate(ID = do.call(str_c, c(select(., mygroup), sep = "_")))
    

    这给了

    # A tibble: 2 × 4
      PERIOD CODE  VALUE ID
       <dbl> <chr> <dbl> <chr> 
    1   1995 A        10 1995_A
    2   1996 B        20 1996_B
    
        3
  •  2
  •   SamR    7 月前

    当您装载时 tidyverse ,我认为这样做的自然方式是使用 tidyr::unite() 将多个列粘贴到一个列中的便利功能 ,以及 !!! splice operator 注入动态传递的列名。

    df |>
        unite(
            "ID", !!!mygroup,
            remove = FALSE # don't delete the pasted columns
        )
    
    # # A tibble: 2 × 4
    #   ID     PERIOD CODE  VALUE
    #   <chr>   <dbl> <chr> <dbl>
    # 1 1995_A   1995 A        10
    # 2 1996_B   1996 B        20
    
        4
  •  1
  •   Luigi    7 月前

    也许是这样的?

     df %>%
          mutate(id = paste(eval(parse(text = mygroup[1])),
                            eval(parse(text = mygroup[2])), sep = "_"))
        
        # A tibble: 2 × 4
          PERIOD CODE  VALUE id    
           <dbl> <chr> <dbl> <chr> 
        1   1995 A        10 1995_A
        2   1996 B        20 1996_B
    
        5
  •  1
  •   maike    7 月前

    如果你想使用tidyverse,你可以使用以下组合 rowwise() c_across() 诚然,对于如此简单的任务,需要相当多的代码

    df %>% 
      mutate(across(all_of(mygroup), as.character)) %>% 
      rowwise() %>% 
      mutate(ID = paste(c_across(all_of(mygroup)), collapse = '_')) %>% 
      ungroup()
    #> # A tibble: 2 × 4
    #>   PERIOD CODE  VALUE ID    
    #>   <chr>  <chr> <dbl> <chr> 
    #> 1 1995   A        10 1995_A
    #> 2 1996   B        20 1996_B
    

    创建于2024年12月11日 reprex v2.1.1

        6
  •  1
  •   tmfmnk    7 月前

    另一种可能 tidyverse 风味:

    df %>%
     mutate(ID = pmap_chr(across(all_of(mygroup)), ~ paste(..., sep = "_")))
    
      PERIOD CODE  VALUE ID    
       <dbl> <chr> <dbl> <chr> 
    1   1995 A        10 1995_A
    2   1996 B        20 1996_B