【问题标题】:How to attach a suffix to `.value` when using `pivot_longer()` and `names_pattern`使用 `pivot_longer()` 和 `names_pattern` 时如何将后缀附加到 `.value`
【发布时间】:2021-06-09 07:17:56
【问题描述】:

我想使用来自 {tidyr} 的 pivot_longer()names_pattern 将我的数据转换为长格式同时保留列名中模式匹配之一的前缀字符串。

这似乎违反直觉,但我想在应用数据字典清理步骤之前转换为长格式,这需要原始列名。

设置

library(dplyr)
library(tidyr)

d <- tibble(id = 1,
            other_var = "foo",
            suffix_t1_value1 = "a",
            suffix_t1_value2 = "b",
            suffix_t2_value1 = "c",
            suffix_t2_value2 = "d") 

我做了什么

> pivot_longer(d,
               starts_with("suffix"),
               names_pattern = "suffix_t(1|2)_(.*)",
               names_to = c("rep", ".value"))

# A tibble: 2 x 5
     id other_var rep   value1 value2
  <dbl> <chr>     <chr> <chr>  <chr> 
1     1 foo       1     a      b     
2     1 foo       2     c      d    

期望的输出

# A tibble: 2 x 5
     id other_var rep   suffix_t1_value1 suffix_t1_value2
  <dbl> <chr>     <chr> <chr>            <chr>           
1     1 foo       1     a                b               
2     1 foo       2     c                d               

我尝试过的

尝试 1

> pivot_longer(d,
               starts_with("suffix"),
               names_pattern = "suffix_t(1|2)_(.*)",
               names_to = c("rep", "suffix_t1_{.value}"))

尝试 2

> pivot_longer(d,
               starts_with("suffix"),
               names_pattern = "suffix_t(1|2)_(.*)",
               names_to = c("rep", paste0("suffix_t1_", ".value")))

【问题讨论】:

    标签: r tidyr


    【解决方案1】:

    我假设您想在pivot_longer 中一步完成。我还没有弄清楚,如果可能的话,但是如果两步过程就可以了,那么下面的方法应该可以工作:

    library(dplyr)
    library(tidyr)
    
    d %>% pivot_longer(starts_with("suffix"),
                       names_pattern = "suffix_t(1|2)_(.*)",
                       names_to = c("rep", ".value")
                 ) %>% 
      rename_with(~ gsub("(.*)", "suffix_t1_\\1", .x),
                  starts_with("value"))
    
    #> # A tibble: 2 x 5
    #>      id other_var rep   suffix_t1_value1 suffix_t1_value2
    #>   <dbl> <chr>     <chr> <chr>            <chr>           
    #> 1     1 foo       1     a                b               
    #> 2     1 foo       2     c                d
    

    reprex package (v0.3.0) 于 2021-06-09 创建


    更新

    在深入研究pivot_longer 之后,我认为不可能在paste 中访问.value,而且似乎不支持粘合语法{.value}

    但是,{tidyr} 提供了使用 build_longer_spec 进行旋转的构建块,它允许我们创建自己的 my_pivot_longer 函数,我们可以在其中包含一个 names_fn 参数,它将一个函数应用于新的列名,并且这里我们可以使用gsub添加前缀或后缀。

    my_pivot_longer <- function(data,
                                cols,
                                names_to = "name",
                                names_pattern = NULL,
                                names_fn = NULL) {
      
      spec <- build_longer_spec(data,
                                cols,
                                names_pattern = names_pattern,
                                names_to = names_to)
    
      if (!is.null(names_fn)) {
        fn <- rlang::as_function(names_fn)
        spec$.value <-  fn(spec$.value)
      }
      
      pivot_longer_spec(data, spec)
        
    }
    
    d %>% 
      my_pivot_longer(starts_with("suffix"),
                      names_pattern = "suffix_t(1|2)_(.*)",
                      names_to = c("rep", ".value"),
                      names_fn = ~ gsub("(.*)", "suffix_t1_\\1", .x))
    #> Note: Using an external vector in selections is ambiguous.
    #> ℹ Use `all_of(cols)` instead of `cols` to silence this message.
    #> ℹ See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
    
    #> This message is displayed once per session.
    #> # A tibble: 2 x 5
    #>      id other_var rep   suffix_t1_value1 suffix_t1_value2
    #>   <dbl> <chr>     <chr> <chr>            <chr>           
    #> 1     1 foo       1     a                b               
    #> 2     1 foo       2     c                d
    

    reprex package (v0.3.0) 于 2021-06-09 创建

    【讨论】:

    • 是的,我也有 2 个步骤。 “value1”和“value2”是占位符,值可以是任何值,例如(“dob”、“gender”)...
    • @Paul:我研究的时间越长,我认为一步就能实现的可能性越小,除非您编写自己的 pivot_longerfunction(请参阅我的更新答案)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 2018-02-28
    相关资源
    最近更新 更多