我有一些数据的结构如下:
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))