R 根据两个正则表达式将字符串拆分为两列



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

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列中即可。

你可以使用基函数来做到这一点,只需将 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

您可以使用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))

最新更新