在特定字符处分割字符串并保留该字符

时间:2019-06-03 18:15:17

标签: r dplyr character

我找到了其他语言的答案,但没有找到R的答案,如果这是重复的,我深表歉意。

我在R中使用separate()函数,并且很好奇是否有可能在出现某个字符时将一列分为两列。例如:

data

    ID          Value
0011ER00      91346
0011ER46      59961
0011ER4610    53968
0011ER4620    55083
0011ER4630    51112
0011ER4640    67480
0011ER4650    45612
0011ER4660    53968

我想拆分ID列,以便数据看起来像这样:

data

Code    Region  Value
0011    ER00    91346
0011    ER46    59961
0011    ER4610  53968
0011    ER4620  55083
0011    ER4630  51112
0011    ER4640  67480
0011    ER4650  45612
0011    ER4660  53968

我尝试了以下代码:

data %>% 
  separate(ID, into = c("Code", "Region"), sep = "E")

但是我不能在结果中保留E并得到:

Code    Region  Value
0011    ER00    91346
0011    R46     59961
0011    R4610   53968
0011    R4620   55083
0011    R4630   51112
0011    R4640   67480
0011    R4650   45612
0011    R4660   53968

2 个答案:

答案 0 :(得分:3)

一个选择是对正则表达式进行环视,以在数字和字符之间的交界处进行拆分。在这里,我们还通过在任意数字的交界处拆分后跟字母“ E”的方式使它更具通用性

library(dplyr)
library(tidyr)
data %>% 
   separate(ID, into = c("Code", "Region"), sep = "(?<=[0-9])(?=E)")
#  Code Region Value
#1 0011   ER00 91346
#2 0011   ER46 59961
#3 0011 ER4610 53968
#4 0011 ER4620 55083
#5 0011 ER4630 51112
#6 0011 ER4640 67480
#7 0011 ER4650 45612
#8 0011 ER4660 53968

或者另一种选择是在,str_replace之前插入定界符,然后执行separate

data %>%
   mutate(ID = str_replace(ID, "E", ",E")) %>% 
   separate(ID, into = c("Code", "Region"))

数据

data <- structure(list(ID = c("0011ER00", "0011ER46", "0011ER4610", "0011ER4620", 
"0011ER4630", "0011ER4640", "0011ER4650", "0011ER4660"), Value = c(91346L, 
59961L, 53968L, 55083L, 51112L, 67480L, 45612L, 53968L)), 
 class = "data.frame", row.names = c(NA, 
-8L))

答案 1 :(得分:1)

我们可以使用extract中的tidyrregex参数与捕获组匹配(用括号括起来),并将它们分成into参数中指定的变量。请注意,捕获组的数量必须等于into变量名称的数量:

library(dplyr)
library(tidyr)

data %>%
  extract(ID, c("Code", "Region"), regex = "(^\\d+)([[:alpha:]]+\\d+)")

输出:

  Code Region Value
1 0011   ER00 91346
2 0011   ER46 59961
3 0011 ER4610 53968
4 0011 ER4620 55083
5 0011 ER4630 51112
6 0011 ER4640 67480
7 0011 ER4650 45612
8 0011 ER4660 53968

数据:

data <- structure(list(ID = structure(1:8, .Label = c("0011ER00", "0011ER46", 
"0011ER4610", "0011ER4620", "0011ER4630", "0011ER4640", "0011ER4650", 
"0011ER4660"), class = "factor"), Value = c(91346L, 59961L, 53968L, 
55083L, 51112L, 67480L, 45612L, 53968L)), class = "data.frame", row.names = c(NA, 
-8L))

extractseparate

与使用separate(在@akrun的答案中)相反,extract专门匹配输出变量的内容,而separate匹配分隔符(或零长度位置)如果是环顾四周)。两者都是有效的,各有利弊。

根据您的用例,separate通常更有用,如果您想基于某个定界符将变量分为多个列,而无需知道输出变量的内容。

当必须确保从输入中获取每个输出变量的正确字符时,

extract更为有用。

在OP的情况下,这并不重要,因为他/她仅使用一个“定界符”将输入分为两个变量,并且输出的级联与输入完全匹配。