【问题标题】:Separate column by matching strings通过匹配字符串分隔列
【发布时间】:2020-07-31 10:20:17
【问题描述】:

我的数据框看起来或多或少像这样:

name_position
RAHEEM STERLINGForward
MARCUS RASHFORDForward
JORDAN HENDERSONMidfielder
JORDAN PICKFORDGoalkeeper
KYLE WALKERDefender

我的目的是创建前一列的两列,因此我创建了一个包含所有可用位置的向量

positions <- c("Goalkeeper", "Defender", "Midfielder", "Forward")

然后我一直在尝试使用诸如separate()、extract() 甚至str_match 之类的函数,但我无法获得我想要达到的输出,看起来是这样的:

name                   position
RAHEEM STERLING        Forward
MARCUS RASHFORD        Forward
JORDAN HENDERSON       Midfielder
JORDAN PICKFORD        Goalkeeper
KYLE WALKER            Defender

【问题讨论】:

    标签: r regex dplyr tidyr stringr


    【解决方案1】:

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

    library(dplyr)
    library(tidyr)
    df1 %>%
      separate(name_position, into = c("name", "position"), 
               sep="(?<=[A-Z])(?=[A-Z][a-z])")
    #             name   position
    #1  RAHEEM STERLING    Forward
    #2  MARCUS RASHFORD    Forward
    #3 JORDAN HENDERSON Midfielder
    #4  JORDAN PICKFORD Goalkeeper
    #5      KYLE WALKER   Defender
    

    如果我们有自定义向量,那么一种选择是通过创建单个字符串来创建 pattern 向量

    library(stringr)
    pat <- str_c(positions, collapse="|")
    df1 %>% 
       transmute(name = str_remove(name_position, pat),
                position = str_extract(name_position, pat))
    

    数据

    df1 <- structure(list(name_position = c("RAHEEM STERLINGForward", "MARCUS RASHFORDForward", 
    "JORDAN HENDERSONMidfielder", "JORDAN PICKFORDGoalkeeper", 
    "KYLE WALKERDefender"
    )), class = "data.frame", row.names = c(NA, -5L))
    

    【讨论】:

      【解决方案2】:

      使用str_extract来自stringr:

      df1$position <- str_extract(df1$name_position, "(?<=[A-Z])[A-Z][a-z]+")
      

      结果:

      df1
                     name_position   position
      1     RAHEEM STERLINGForward    Forward
      2     MARCUS RASHFORDForward    Forward
      3 JORDAN HENDERSONMidfielder Midfielder
      4  JORDAN PICKFORDGoalkeeper Goalkeeper
      5        KYLE WALKERDefender   Defender
      

      此解决方案使用正向回溯:

      (?&lt;=[A-Z]) 如果你在左边看到一个大写字母...

      [A-Z][a-z]+ ... 匹配后面的大写字母加上它后面的一个或多个小写字母

      【讨论】:

        猜你喜欢
        • 2015-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-31
        • 2014-03-02
        • 2014-02-05
        • 1970-01-01
        相关资源
        最近更新 更多