если есть функция R для отсеивания всех чисел из строки - PullRequest
0 голосов
/ 07 мая 2020

Я работаю над проектом, и для каждого наблюдения есть столбец комментариев. В этом столбце указано, как долго человек оставался в определенном месте. В некоторых комментариях говорится: «2 ночи в А, 2 ночи в Б.» На данный момент я могу отфильтровать только первое число. Есть ли способ вывести из комментария оба числа? Даже если он помещает каждое вытянутое число в новую строку.

Ответы [ 4 ]

2 голосов
/ 07 мая 2020

Tidy way;),

x <- "2 nights in A, 2 nights in B."

library(stringr)
str_extract_all(x, "\\d+")

выводит результат как

[[1]]
[1] "2" "2"

Edit

str_extract_all(x, "\\d+") %>% unlist

выводит как:

[1] "2" "2"
2 голосов
/ 07 мая 2020

вы можете использовать scan + gsub. Используйте gsub, чтобы удалить все нечисловые c элементы

x <- "2 nights in A, 2 nights in B."
scan(text = gsub("\\D+", " ", x))

Read 2 items
[1] 2 2

, конечно, вы можете включить параметр quiet. ie scan(text = gsub("\\D", " ", x), quiet = TRUE)

2 голосов
/ 07 мая 2020

Для базовой опции R мы можем попробовать использовать grepexpr вместе с regmatches:

x <- "2 nights in A, 2 nights in B."
y <- regmatches(x, gregexpr("\\b\\d+\\b", x))[[1]]
y

[1] "2" "2"

Это сгенерирует вектор, содержащий все числа в каждой отдельной строке ввода.

0 голосов
/ 07 мая 2020

Из вашего сообщения не ясно, хотите ли вы , чтобы имела отдельную запись для каждого найденного вами числа. Если вы это сделаете, вы можете создать список из каждой записи, содержащей числа, а затем unnest список, чтобы получить несколько строк.

library(tidyverse)
inputTbl <- tibble(record = 1:2,
       comment = c("3 night in A", "2 nights in A, 1 nights in B."))

inputTbl %>% 
  mutate(numNight = map(comment, ~  unlist(str_extract_all(.x, "\\d+")))) %>% 
  unnest() %>% 
  mutate(numNight = as.double(numNight))

Результат:

# A tibble: 3 x 3
  record comment                       numNight
   <int> <chr>                         <dbl>   
1      1 3 night in A                  3       
2      2 2 nights in A, 1 nights in B. 2       
3      2 2 nights in A, 1 nights in B. 1 

И если вы хотите захватить и отель, вы можете построить тибл и разложить его.

inputTbl <- tibble(record = 1:2,
       comment = c("3 night in Sheraton", "2 Nights in Waldorf, 1 night in Sands."))

inputTbl %>% 
  mutate(numNight = 
           map(comment,
                ~  tibble(Nights = unlist(str_extract_all(.x, "\\d+")),
                          Hotel = unlist(str_extract_all(.x, 
                                 "(?ix)                    # Perl-style regex, space+case insensitive
                                  (?<= nights? \\s in \\s) # Detect 'nights in'; dont caputre
                                  (\\w+)                   # The hotel
                                 "))))) %>% 
  unnest()
# A tibble: 3 x 4
  record comment                                Nights Hotel   
   <int> <chr>                                  <chr>  <chr>   
1      1 3 night in Sheraton                    3      Sheraton
2      2 2 Nights in Waldorf, 1 night in Sands. 2      Waldorf 
3      2 2 Nights in Waldorf, 1 night in Sands. 1      Sands   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...