【问题标题】:How to extract information from string column in R?如何从 R 中的字符串列中提取信息?
【发布时间】:2022-11-24 00:50:34
【问题描述】:

我有以下数据框:

df <- structure(list(Page = c("/es/import-340600-to-mx-from-de/summary", 
"/es/import-340600-to-de-from-mx/summary", "/es/import-071320-to-sv-from-cr/summary", 
"/en/import-340111-to-ru-from-ir/summary", "/en/import-870423-to-hk-from-de/summary", 
"/es/import-392049-to-mx-from-de/summary", "/es/import-080440-to-mx-from-es/summary", 
"/es/import-340600-to-mx-from-jp/summary", "/en/import-852691-to-tr-from-ua/summary", 
"/es/import-180620-to-mx-from-us/summary"), Count = c(153, 78, 
72, 58, 57, 55, 48, 46, 42, 42)), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -10L))

   Page                                    Count
   <chr>                                   <dbl>
 1 /es/import-340600-to-mx-from-de/summary   153
 2 /es/import-340600-to-de-from-mx/summary    78
 3 /es/import-071320-to-sv-from-cr/summary    72
 4 /en/import-340111-to-ru-from-ir/summary    58
 5 /en/import-870423-to-hk-from-de/summary    57
 6 /es/import-392049-to-mx-from-de/summary    55
 7 /es/import-080440-to-mx-from-es/summary    48
 8 /es/import-340600-to-mx-from-jp/summary    46
 9 /en/import-852691-to-tr-from-ua/summary    42
10 /es/import-180620-to-mx-from-us/summary    42

例如,从下面的这一行,我如何提取并放置MX分为 2 个单独的列?对表格的其余部分做同样的事情

1 /es/import-340600-to-mx-from-de/summary   153

预期输出:

……

【问题讨论】:

    标签: r string dplyr substring substr


    【解决方案1】:

    另一个解决方案:

    df %>%
      mutate(To = str_extract(Page, "(?<=to-)\w+"),
             From = str_extract(Page, "(?<=from-)\w+"))
    
    # A tibble: 10 × 4
       Page                                    Count To    From 
       <chr>                                   <dbl> <chr> <chr>
     1 /es/import-340600-to-mx-from-de/summary   153 mx    de   
     2 /es/import-340600-to-de-from-mx/summary    78 de    mx   
     3 /es/import-071320-to-sv-from-cr/summary    72 sv    cr   
     4 /en/import-340111-to-ru-from-ir/summary    58 ru    ir   
     5 /en/import-870423-to-hk-from-de/summary    57 hk    de   
     6 /es/import-392049-to-mx-from-de/summary    55 mx    de   
     7 /es/import-080440-to-mx-from-es/summary    48 mx    es   
     8 /es/import-340600-to-mx-from-jp/summary    46 mx    jp   
     9 /en/import-852691-to-tr-from-ua/summary    42 tr    ua   
    10 /es/import-180620-to-mx-from-us/summary    42 mx    us 
    

    甚至:

    df %>%
      extract(Page, c("to","from"), "to-(\w+)-from-(\w+)", remove = FALSE)
    
    # A tibble: 10 × 4
       Page                                    to    from  Count
       <chr>                                   <chr> <chr> <dbl>
     1 /es/import-340600-to-mx-from-de/summary mx    de      153
     2 /es/import-340600-to-de-from-mx/summary de    mx       78
     3 /es/import-071320-to-sv-from-cr/summary sv    cr       72
     4 /en/import-340111-to-ru-from-ir/summary ru    ir       58
     5 /en/import-870423-to-hk-from-de/summary hk    de       57
     6 /es/import-392049-to-mx-from-de/summary mx    de       55
     7 /es/import-080440-to-mx-from-es/summary mx    es       48
     8 /es/import-340600-to-mx-from-jp/summary mx    jp       46
     9 /en/import-852691-to-tr-from-ua/summary tr    ua       42
    10 /es/import-180620-to-mx-from-us/summary mx    us       42
    

    【讨论】:

    • 啊...我假设str_extract不支持lookbehind ...
    • @r2evans 但你为什么会这么认为?
    【解决方案2】:

    另一个 dplyr 选项:

    library(dplyr)
    
    df %>%
      mutate(from = sub("^.*from-(.*)/.*$", "\1", Page),
             to   = sub("^.*to-(.*?)-.*$", "\1", Page)) %>%
      select(-Page)
    #> # A tibble: 10 x 3
    #>    Count from  to   
    #>    <dbl> <chr> <chr>
    #>  1   153 de    mx   
    #>  2    78 mx    de   
    #>  3    72 cr    sv   
    #>  4    58 ir    ru   
    #>  5    57 de    hk   
    #>  6    55 de    mx   
    #>  7    48 es    mx   
    #>  8    46 jp    mx   
    #>  9    42 ua    tr   
    #> 10    42 us    mx
    

    创建于 2022-11-23 reprex v2.0.2

    【讨论】:

      【解决方案3】:

      我们可以为此使用strcapture:它接受一个带有一个或多个(.)组的正则表达式,一个向量,并根据proto=中存在的字段/类返回一个data.frame。如果未找到任何组,则不会找到任何组。

      基础R

      cbind(df, strcapture(".*-to-([^-/]*)-from-([^-/]*).*", df$Page, proto=list(to="", from="")))
      #                                       Page Count to from
      # 1  /es/import-340600-to-mx-from-de/summary   153 mx   de
      # 2  /es/import-340600-to-de-from-mx/summary    78 de   mx
      # 3  /es/import-071320-to-sv-from-cr/summary    72 sv   cr
      # 4  /en/import-340111-to-ru-from-ir/summary    58 ru   ir
      # 5  /en/import-870423-to-hk-from-de/summary    57 hk   de
      # 6  /es/import-392049-to-mx-from-de/summary    55 mx   de
      # 7  /es/import-080440-to-mx-from-es/summary    48 mx   es
      # 8  /es/import-340600-to-mx-from-jp/summary    46 mx   jp
      # 9  /en/import-852691-to-tr-from-ua/summary    42 tr   ua
      # 10 /es/import-180620-to-mx-from-us/summary    42 mx   us
      

      dplyr

      library(dplyr)
      df %>%
        mutate(strcapture(".*-to-([^-/]*)-from-([^-/]*).*", Page, list(to="", from="")))
      # # A tibble: 10 x 4
      #    Page                                    Count to    from 
      #    <chr>                                   <dbl> <chr> <chr>
      #  1 /es/import-340600-to-mx-from-de/summary   153 mx    de   
      #  2 /es/import-340600-to-de-from-mx/summary    78 de    mx   
      #  3 /es/import-071320-to-sv-from-cr/summary    72 sv    cr   
      #  4 /en/import-340111-to-ru-from-ir/summary    58 ru    ir   
      #  5 /en/import-870423-to-hk-from-de/summary    57 hk    de   
      #  6 /es/import-392049-to-mx-from-de/summary    55 mx    de   
      #  7 /es/import-080440-to-mx-from-es/summary    48 mx    es   
      #  8 /es/import-340600-to-mx-from-jp/summary    46 mx    jp   
      #  9 /en/import-852691-to-tr-from-ua/summary    42 tr    ua   
      # 10 /es/import-180620-to-mx-from-us/summary    42 mx    us   
      

      如果你需要在另一个不存在的情况下抓住一个,那么也许:

      df %>%
        mutate(to = stringr::str_match(Page, ".*-to-([^/-]*)")[,2], from = stringr::str_match(Page, ".*-from-([^/-]*)")[,2])
      # # A tibble: 10 x 4
      #    Page                                    Count to    from 
      #    <chr>                                   <dbl> <chr> <chr>
      #  1 /es/import-340600-to-mx-from-de/summary   153 mx    de   
      #  2 /es/import-340600-TO-de-from-mx/summary    78 NA    mx   
      #  3 /es/import-071320-to-sv-from-cr/summary    72 sv    cr   
      #  4 /en/import-340111-to-ru-from-ir/summary    58 ru    ir   
      #  5 /en/import-870423-to-hk-from-de/summary    57 hk    de   
      #  6 /es/import-392049-to-mx-from-de/summary    55 mx    de   
      #  7 /es/import-080440-to-mx-from-es/summary    48 mx    es   
      #  8 /es/import-340600-to-mx-from-jp/summary    46 mx    jp   
      #  9 /en/import-852691-to-tr-from-ua/summary    42 tr    ua   
      # 10 /es/import-180620-to-mx-from-us/summary    42 mx    us   
      

      或更一般地(一个或多个这样的模式):

      df %>%
        mutate(as.data.frame(lapply(
          setNames(nm = c("to", "from")),
          function(ptn) stringr::str_match(Page, sprintf(".*-%s-([^/-]*)", ptn))[,2])
        ))
      # # A tibble: 10 x 4
      #    Page                                    Count to    from 
      #    <chr>                                   <dbl> <chr> <chr>
      #  1 /es/import-340600-to-mx-from-de/summary   153 mx    de   
      #  2 /es/import-340600-TO-de-from-mx/summary    78 NA    mx   
      #  3 /es/import-071320-to-sv-from-cr/summary    72 sv    cr   
      #  4 /en/import-340111-to-ru-from-ir/summary    58 ru    ir   
      #  5 /en/import-870423-to-hk-from-de/summary    57 hk    de   
      #  6 /es/import-392049-to-mx-from-de/summary    55 mx    de   
      #  7 /es/import-080440-to-mx-from-es/summary    48 mx    es   
      #  8 /es/import-340600-to-mx-from-jp/summary    46 mx    jp   
      #  9 /en/import-852691-to-tr-from-ua/summary    42 tr    ua   
      # 10 /es/import-180620-to-mx-from-us/summary    42 mx    us   
      

      【讨论】:

      • 非常好!我以前没有遇到过strcapture
      • 当 base R 是要求/偏好时,这很棒。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-25
      • 2017-09-19
      • 2015-03-18
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      相关资源
      最近更新 更多