【问题标题】:R Split strings into two columns based on TWO regular expressionsR根据两个正则表达式将字符串拆分为两列
【发布时间】:2021-09-18 19:34:23
【问题描述】:

我有一些结构如下的数据:

ID   Region            Value
1    Europe            8
2    Europe: Class 1   6
3    Asia: System 2    6
4    North America     7
5    Europe: System 1  5
6    Africa            7
7    Africa: Class 2   5
8    South America     9
9    Europe: System 1  3
10   Europe            7

我想要做的是创建一个名为 Class 的新列,它添加了在 Region 列中提到“类”和“系统”的实例 - 如果不清楚我的意思,请查看我的预期输出如下。我知道这可以通过separate 函数来完成,但我认为您只能为代码的分隔符部分指定一个值。例如。 sep = ": Class" 只会拆分提及“类”的实例,但我也想拆分任何提及“系统”的实例。这可以在一行代码中完成,还是我需要在这里做一些更复杂的事情?这是我的最终数据的外观:

ID   Region            Class  Value
1    Europe                   8
2    Europe            1      6
3    Asia              2      6
4    North America            7
5    Europe            1      5
6    Africa                   7
7    Africa            2      5
8    South America            9
9    Europe            1      3
10   Europe                   7

请注意,我想从Region 列中删除对“类”或“系统”(包括冒号)的任何引用,并将数值添加到新的Class 列中。

【问题讨论】:

  • 我刚刚想到的一个解决方案是首先将“:System”的所有实例替换为“:Class”。这样,我可以通过“:Class”分隔并获得所需的结果。这是最简单的解决方案吗?

标签: r regex split


【解决方案1】:

您可以通过将 strsplit 与以": System" 或": Class" 作为符号的正则表达式一起使用来使用基本函数:

splitted = strsplit(df$Region,"(: Class)|(: System)")
df$Region = lapply(splitted,FUN=function(x){x[1]})
df$Class = lapply(splitted,FUN=function(x){x[2]})

结果是:

> df
   ID        Region Value Class
1   1        Europe     8    NA
2   2        Europe     6     1
3   3          Asia     6     2
4   4 North America     7    NA
5   5        Europe     5     1
6   6        Africa     7    NA
7   7        Africa     5     2
8   8 South America     9    NA
9   9        Europe     3     1
10 10        Europe     7    NA

【讨论】:

    【解决方案2】:

    您可以使用str_extract 提取数字并使用str_remove 删除不需要的文本。

    library(dplyr)
    library(stringr)
    
    df %>%
      mutate(Class = str_extract(Region, '(?<=(Class|System)\\s)\\d+'), 
             Region = str_remove(Region, ':\\s*(Class|System)\\s*\\d+'))
    
    #   ID        Region Value Class
    #1   1        Europe     8  <NA>
    #2   2        Europe     6     1
    #3   3          Asia     6     2
    #4   4 North America     7  <NA>
    #5   5        Europe     5     1
    #6   6        Africa     7  <NA>
    #7   7        Africa     5     2
    #8   8 South America     9  <NA>
    #9   9        Europe     3     1
    #10 10        Europe     7  <NA>
    

    str_extract 提取'Class' 之后的数字 或'System'。如果这些词不存在,则返回NA。

    str_remove 删除冒号,后跟零个或多个空格 (\\s*),后跟 'Class' 或 'System' 和一个数字 (\\d+)。

    数据

    如果您以易于复制的可重现格式提供数据,则更容易提供帮助。

    df <- structure(list(ID = 1:10, Region = c("Europe", "Europe: Class 1", 
    "Asia: System 2", "North America", "Europe: System 1", "Africa", 
    "Africa: Class 2", "South America", "Europe: System 1", "Europe"
    ), Value = c(8L, 6L, 6L, 7L, 5L, 7L, 5L, 9L, 3L, 7L)), 
    class = "data.frame", row.names = c(NA, -10L))
    

    【讨论】:

    • 这就像一个魅力 - 非常感谢。我不是程序员,但我想了解它是如何/为什么起作用的。是不是第一行代码创建了一个名为Class 的新列,它从Region 列中提取指定的正则表达式?并且您使用了“|”符号来指定两个表达式?然后第二行代码从Region 列中删除这两个表达式。此外,适当注意以可重现的格式提供数据 - 下次会这样做! :)
    • 是的,我编辑了答案以包含有关代码的更多解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 2017-02-10
    相关资源
    最近更新 更多