【问题标题】:tidyr extract regular expression [duplicate]tidyr 提取正则表达式
【发布时间】:2016-09-09 23:13:56
【问题描述】:

我有一个数据框,其中包含一些变量和场景的一些统计信息。数据如下:

df <- data.frame(
  Scenario = c('base','stress','extreme'),
  x_min = c(-3,-2, -2.5),
  x_mean = c(0,0.25, 1),
  x_max = c(2, 1, 3),
  y_min = c(-1.5, -2, -3),
  y_mean = c(1, 2, 3),
  y_max = c(5, 3, 3.5),
  z_min = c(0, 1, 3),
  z_mean = c(0.25, 2, 5),
  z_max = c(2, 4, 7)
)

   Scenario x_min x_mean x_max y_min y_mean y_max z_min z_mean z_max
1     base  -3.0   0.00     2  -1.5      1   5.0     0   0.25     2
2   stress  -2.0   0.25     1  -2.0      2   3.0     1   2.00     4
3  extreme  -2.5   1.00     3  -3.0      3   3.5     3   5.00     7

我想使用 tidyr 的收集和提取函数(与 Hadley 对 this question 的回答类似)来获取以下格式的数据:

new_df
    Scenario variable  min  mean   max
1     base        x   -3.0  0.00   2.0
2   stress        x   -2.0  0.25   1.0
3  extreme        x   -2.5  1.00   3.0
4     base        y   -1.5  1.00   5.0
5   stress        y   -2.0  2.00   3.0
6  extreme        y   -3.0  3.00   3.5
7     base        z    0.0  0.25   2.0
8   stress        z    1.0  2.00   4.0
9  extreme        z    3.0  5.00   7.0

到目前为止我的命令看起来像:

new_df <- df %>%
            gather(key, value, -Scenario) %>%
            extract(key, c("min", "mean", "max"), "regex")

这是我正在努力解决的正则表达式。按照上面提到的问题的答案,我试过了:

"_min|_mean|_max" --> idea being to capture the 3 different groups

我得到的错误看起来像:

 Error in names(l) <- into : 
     'names' attribute [3] must be the same length as the vector [0]

我认为这个错误的意思是正则表达式没有“找到”3个组来排序到我通过它的c("min","mean","max")

什么正则表达式可以使它工作?或者还有其他更好的方法吗?

【问题讨论】:

    标签: regex r dplyr extract tidyr


    【解决方案1】:

    你只需要

    df %>% gather(var, val, -Scenario) %>% 
        separate(var, into = c('var', 'stat'), sep = '_') %>% 
        spread(stat, val)
    #   Scenario var max mean  min
    # 1     base   x 2.0 0.00 -3.0
    # 2     base   y 5.0 1.00 -1.5
    # 3     base   z 2.0 0.25  0.0
    # 4  extreme   x 3.0 1.00 -2.5
    # 5  extreme   y 3.5 3.00 -3.0
    # 6  extreme   z 7.0 5.00  3.0
    # 7   stress   x 1.0 0.25 -2.0
    # 8   stress   y 3.0 2.00 -2.0
    # 9   stress   z 4.0 2.00  1.0
    

    由于您的初始列名的格式很好,用下划线分隔变量和统计信息,因此只需 separate 将它们分成两列。 spread 将从长到宽重新排列。

    【讨论】:

    • 正是我需要的!作为说明,我必须将separatesep 参数设为正则表达式,因为我的列标题实际上包含多个下划线(例如stat_1_min, stat_2_min)。我使用的正则表达式是(_)(?!.*_)
    【解决方案2】:

    这可以通过data.table 中的melt 轻松完成,因为它可以在measure 中使用多个patterns

    library(data.table)
    nm1 <- unique(substr(names(df)[-1], 1, 1))
    melt(setDT(df), measure = patterns("min$", "mean$", "max$"),
           value.name= c("min", "mean", "max"))[, variable := nm1[variable]][]
    #   Scenario variable  min mean max
    #1:     base        x -3.0 0.00 2.0
    #2:   stress        x -2.0 0.25 1.0
    #3:  extreme        x -2.5 1.00 3.0
    #4:     base        y -1.5 1.00 5.0
    #5:   stress        y -2.0 2.00 3.0
    #6:  extreme        y -3.0 3.00 3.5
    #7:     base        z  0.0 0.25 2.0
    #8:   stress        z  1.0 2.00 4.0
    #9:  extreme        z  3.0 5.00 7.0
    

    【讨论】:

      猜你喜欢
      • 2018-09-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多