【问题标题】:Pivot_longer with regex for two-digit numbers in names_pattern带有正则表达式的 Pivot_longer 用于 names_pattern 中的两位数
【发布时间】:2021-11-23 14:31:59
【问题描述】:

我有一个大型的宽格式数据集,其中包含在多个波测量的许多变量,每个变量波组合(例如age1、age2、age3、age4)有一列,以及一些时间固定的变量(例如 ID、性别)。旋转后,我希望每个变量都由一个列表示,旁边是一个新的“波浪”列。

它工作得几乎完美,只是我无法在同一列中表示第 1-9 波和第 10-13 波。

df <- data.frame(
  ID = c(10001,10002),
  Sex = c(1,2),
  Age1 = c(73,25),
  Age2 = c(74,26),
  Age3=c(75,27),
  Age4 = c(76,28),
  Age5 = c(77,29),
  Age6=c(78,30),
  Age7 = c(79,31),
  Age8 = c(80,31),
  Age9=c(81,33),
  Age10=c(82,34),
  Age11 = c(83,35),
  Age12 = c(84,36),
  Age13=c(85,37)
)

names_test<-names(df) 
no_numb<-grep("*[A-Za-z]$", names_test) #to identify all the column names ending with a letter, which I do NOT want to pivot into longer form

df_long<-pivot_longer(df,cols = !no_numb, names_to = c('.value',"wave"),
                  names_pattern = "(.*)(\\d+)$")

长数据输出:

> df_long
# A tibble: 20 x 5
      ID   Sex wave    Age  Age1
   <dbl> <dbl> <chr> <dbl> <dbl>
 1 10001     1 1        73    83
 2 10001     1 2        74    84
 3 10001     1 3        75    85
 4 10001     1 4        76    NA
 5 10001     1 5        77    NA
 6 10001     1 6        78    NA
 7 10001     1 7        79    NA
 8 10001     1 8        80    NA
 9 10001     1 9        81    NA
10 10001     1 0        NA    82
11 10002     2 1        25    35
12 10002     2 2        26    36
13 10002     2 3        27    37
14 10002     2 4        28    NA
15 10002     2 5        29    NA
16 10002     2 6        30    NA
17 10002     2 7        31    NA
18 10002     2 8        31    NA
19 10002     2 9        33    NA
20 10002     2 0        NA    34

如您所见,有一个 Age 列,它具有波 1-9 的值,还有一个 Age1 列,它具有 1、2、3 和 0 的值(即 Age10、Age11、Age12、Age13 )。 我认为这里的问题是 names_to 参数或 names_pattern 参数。任何帮助将不胜感激!

【问题讨论】:

    标签: r regex tidyr


    【解决方案1】:

    .* 是贪心的,所以它采用最大匹配字符串。你可以使用

    pivot_longer(df,cols = !no_numb, names_to = c('.value',"wave"),
                      names_pattern = "(Age)(\\d+)$")
    

    改为或通过添加 ? 使其不贪婪

    pivot_longer(df,cols = !no_numb, names_to = c('.value',"wave"),
                      names_pattern = "(.*?)(\\d+)$")
    

    返回

    # A tibble: 26 x 4
          ID   Sex wave    Age
       <dbl> <dbl> <chr> <dbl>
     1 10001     1 1        73
     2 10001     1 2        74
     3 10001     1 3        75
     4 10001     1 4        76
     5 10001     1 5        77
     6 10001     1 6        78
     7 10001     1 7        79
     8 10001     1 8        80
     9 10001     1 9        81
    10 10001     1 10       82
    # ... with 16 more rows
    

    【讨论】:

    • 非常感谢马丁!这 ?通配符是一个很好的解决方案,因为我可以应用到包含大量变量(不仅仅是年龄)的完整数据集,而无需手动指定它们的名称
    【解决方案2】:

    我们也可以将names_sep 与正则表达式环视一起使用

    library(tidyr)
     pivot_longer(df, cols = starts_with('Age'), 
       names_to = c(".value", "wave"), names_sep = "(?<=[a-z])(?=[0-9])")
    # A tibble: 26 × 4
          ID   Sex wave    Age
       <dbl> <dbl> <chr> <dbl>
     1 10001     1 1        73
     2 10001     1 2        74
     3 10001     1 3        75
     4 10001     1 4        76
     5 10001     1 5        77
     6 10001     1 6        78
     7 10001     1 7        79
     8 10001     1 8        80
     9 10001     1 9        81
    10 10001     1 10       82
    # … with 16 more rows
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-26
      • 2023-01-27
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多