Извлечь все совпадения в новый столбец, используя регулярное выражение в R - PullRequest
3 голосов
/ 09 января 2020

В моих данных у меня есть столбец данных открытого текстового поля, который похож на следующий пример:

d <- tribble(
  ~x,
  "i am 10 and she is 50",
  "he is 32 and i am 22",
  "he may be 70 and she may be 99",
)

Я хотел бы использовать regex для извлечения всех двух чисел di git в новый столбец с именем y. У меня есть следующий код, и он хорошо работает при извлечении первого совпадения:

d %>%
  mutate(y = str_extract(x, "([0-9]{2})"))

# A tibble: 3 x 2
  x                              y    
  <chr>                          <chr>
1 i am 10 and she is 50          10   
2 he is 32 and i am 22           32   
3 he may be 70 and she may be 99 70 

Но есть ли способ извлечь оба числа из двух чисел git в один столбец с некоторым стандартным разделителем (например, запятой) )?

Ответы [ 2 ]

3 голосов
/ 09 января 2020

Мы можем использовать str_extract_all вместо str_extract, поскольку str_extract соответствует только первому экземпляру, где суффикс _all является глобальным и извлечет все экземпляры в list, которые можно преобразовать обратно в два столбца с unnest_wider

library(dplyr)
library(tidyr)
library(stringr)
d %>%  
    mutate(out =  str_extract_all(x, "\\d{2}")) %>% 
    unnest_wider(c(out)) %>%
    rename_at(-1, ~ c('y', 'z')) %>%
    type.convert(as.is = TRUE)
# A tibble: 3 x 3
# x                                  y     z
#  <chr>                          <int> <int>
#1 i am 10 and she is 50             10    50
#2 he is 32 and i am 22              32    22
#3 he may be 70 and she may be 99    70    99

Если нам нужно в качестве строкового столбца с , в качестве разделителя, после извлечения в list, l oop над list с map и объединить все элементы в одну строку с помощью toString (оболочка для paste(., collapse=", "))

library(purrr)
d %>%
   mutate(y = str_extract_all(x, "\\b\\d{2}\\b") %>%
                 map_chr(toString))
# A tibble: 3 x 2
#  x                              y     
#  <chr>                          <chr> 
#1 i am 10 and she is 50          10, 50
#2 he is 32 and i am 22           32, 22
#3 he may be 70 and she may be 99 70, 99
2 голосов
/ 09 января 2020

Мы также можем использовать extract и unite из tidyr:

library(dplyr)
library(tidyr)

d %>%
  extract(x, c('y', 'z'), regex = "(\\d+)[^\\d]+(\\d+)", remove = FALSE) 

Выход:

# A tibble: 3 x 3
  x                              y     z    
  <chr>                          <chr> <chr>
1 i am 10 and she is 50          10    50   
2 he is 32 and i am 22           32    22   
3 he may be 70 and she may be 99 70    99 

Возврат одного столбца:

d %>%
  extract(x, c('y', 'z'), regex = "(\\d+)[^\\d]+(\\d+)", remove = FALSE) %>%
  unite('y', y, z, sep = ', ')

Выход:

# A tibble: 3 x 3
  x                              y     
  <chr>                          <chr> 
1 i am 10 and she is 50          10, 50
2 he is 32 and i am 22           32, 22
3 he may be 70 and she may be 99 70, 99
...