跨多列的pivot_longer,如何使用names_pattern参数

Can*_*ice 1 r tidyr

df_wide <- structure(list(name = c("Crushers GC", "4Aces GC"), first_name = c("Charles", 
"Peter"), last_name = c("Howell III", "Uihlein"), first_name_1 = c("Paul", 
"Pat"), last_name_1 = c("Casey", "Perez"), first_name_2 = c("Bryson", 
"Dustin"), last_name_2 = c("DeChambeau", "Johnson"), first_name_3 = c("Anirban", 
"Patrick"), last_name_3 = c("Lahiri", "Reed")), row.names = c(NA, 
-2L), class = c("tbl_df", "tbl", "data.frame"))

name        first_name last_name  first_name_1 last_name_1 first_name_2 last_name_2 first_name_3 last_name_3
  <chr>       <chr>      <chr>      <chr>        <chr>       <chr>        <chr>       <chr>        <chr>      
1 Crushers GC Charles    Howell III Paul         Casey       Bryson       DeChambeau  Anirban      Lahiri     
2 4Aces GC    Peter      Uihlein    Pat          Perez       Dustin       Johnson     Patrick      Reed       
Run Code Online (Sandbox Code Playgroud)

我们的目标是pivot_longer进入一个包含 3 列的数据框name,代码看起来应该很简单,但是我们不确定要传递给什么值,我们有firstlastnames_pattern

zed %>%
  tidyr::pivot_longer(cols = -name,
                      names_to = c("fname", "lname"),
                      names_pattern = "???")
Run Code Online (Sandbox Code Playgroud)

Maë*_*aël 5

方法如下:

df_wide %>%
  tidyr::pivot_longer(cols = -name,
                      names_pattern = "(.*_name).*",
                      names_to = ".value")

#   name        first_name last_name 
# 1 Crushers GC Charles    Howell III
# 2 Crushers GC Paul       Casey     
# 3 Crushers GC Bryson     DeChambeau
# 4 Crushers GC Anirban    Lahiri    
# 5 4Aces GC    Peter      Uihlein   
# 6 4Aces GC    Pat        Perez     
# 7 4Aces GC    Dustin     Johnson   
# 8 4Aces GC    Patrick    Reed      
Run Code Online (Sandbox Code Playgroud)

解释:

您应该在 中定义现有列的模式names_patternlast_name在这种情况下,您只需要一个为或 的组first_name。您应该使用正则表达式来定义它们:

(.*_name).*
Run Code Online (Sandbox Code Playgroud)

这将匹配包含 的每一列_name。括号用于捕获组。您在预期输出中只需要列名称的第一部分(因此,不是 _1、_2),因此我们仅对一组使用括号。这就是为什么只有一个names_to元素。

在 中names_to,定义新列名称的位置.value指的是:

“.value”表示列名的相应组件定义包含单元格值的输出列的名称,完全覆盖values_to。

这里,.value指的是任何匹配的东西(.*_name),所以两者first_name都是 和last_name。这就是为什么我们最终有两列。如果原始 data.frame 中有middle_name, , ... 列,我们最终会得到第三列。middle_name_1middle_name

  • 喜欢这些详细的解释,甚至比帮助手册更好:) +1! (3认同)