Используйте R для извлечения числовых значений из строки в столбце

#r #string #split

#r #строка #разделить

Вопрос:

У меня есть таблица со следующей структурой столбцов :

 Name                                                Type
Urgent Care (Revenue Code: 0456)                    Per Case
IV Therapy (Revenue Codes 0260, 0269)               Per Visit
Oncology Treatment (Revenue Codes: 0280, 0289)      Per Visit
 

и я хочу извлечь числовые коды доходов из столбца имен, чтобы таблица выглядела так :

 Name                     Rev Code      Type
Urgent Care              0456          Per Case
IV Therapy               0260, 0269    Per Visit
Oncology Treatment       0280, 0289    Per Visit
 

исходные данные несовместимы в столбце Name, поскольку за словом «Code» следует «;» , пробел, «-» и т.д. Итак, я пытался использовать регулярное выражение для поиска первого числа, а затем разделить столбец там.

Я попытался использовать регулярное выражение для поиска первой цифры и separate() из пакета tidyr :

 library(tidyr)
separate(mydata, Name, into = c("Name", "Rev Code"), sep = "[[:digit:]]")
 

который разбивает столбец в нужном месте, но столбец «Rev Code» остается пустым?
Я относительно новичок в R и определенно буду признателен за любую помощь!

Данные:

 structure(list(
Name = c("Urgent Care (Revenue Code: 0456)", "IV Therapy (Revenue Codes 0260, 0269)", 
"Oncology Treatment (Revenue Codes: 0280, 0289)"), 
Type = c("Per Case", "Per Visit", "Per Visit")), 
.Names = c("Name", "Type"), row.names = 1:3, class = "data.frame")
 

Комментарии:

1. согласен. Только что внес это редактирование.

Ответ №1:

 read.table(header=TRUE, stringsAsFactors=FALSE, sep=",", text='Name,Type
"Urgent Care (Revenue Code: 0456)", "Per Case"
"IV Therapy (Revenue Codes 0260, 0269)","Per Visit"
"Oncology Treatment (Revenue Codes: 0280, 0289)", "Per Visit"') -> df

library(stringi)
library(dplyr)
library(purrr)

extract_codes <- function(x) {
  stri_match_all_regex(x, "[[:digit:]] ") %>% # extract the numbers
    map(~paste0(as.vector(.), collapse=", ")) # paste them back together
}

mutate(df, `Rev Code`=extract_codes(Name))
 

Ответ №2:

Мы можем попробовать с extract

 library(tidyr)
extract(df1, Name, into = c("Name", "RevCode"), "([^(] )\s*[^0-9] ([0-9].*).")

#               Name    RevCode      Type
#1        Urgent Care       0456  Per Case
#2         IV Therapy 0260, 0269 Per Visit
#3 Oncology Treatment 0280, 0289 Per Visit
 

Поскольку OP прокомментировал, что существуют другие шаблоны,

 extract(df2, Name, into = c("Name", "RevCode"), "([^(] )\s*[^0-9] ([0-9].*).")
#                 Name         RevCode      Type
#1        Urgent Care             0456  Per Case
#2         IV Therapy       0260, 0269 Per Visit
#3 Oncology Treatment       0280, 0289 Per Visit
#4     Speech Therapy  0440-0444, 0449 Per Visit
 

данные

 df2 <- structure(list(Name = c("Urgent Care (Revenue Code: 0456)", 
 "IV Therapy (Revenue Codes 0260, 0269)", 
"Oncology Treatment (Revenue Codes: 0280, 0289)", 
"Speech Therapy (Revenue Codes: 0440-0444, 0449)"
), Type = c("Per Case", "Per Visit", "Per Visit", "Per Visit"
)), .Names = c("Name", "Type"), class = "data.frame", row.names = c(NA, 
-4L))
 

Комментарии:

1. Это определенно помогло. В данных есть пара строк, которые оставляют закрывающий «)» в столбце RevCode. Не удалось понять, почему. Пара примеров :

2. Логопедия (Коды доходов: 0440-0444, 0449)

3. @user6340762 Шаблон там другой, так как он также имеет -

4. вы правы. То есть в моих данных было немного пробелов, которые я пропустил. Спасибо!

5. @user6340762 В extract , мы записываем как группу. Итак, независимо от того, что находится внутри группы захвата ( (...) ), это тот, который был извлечен. т. е. в первом случае ( ([^(] ) ) это один или несколько символов, которые не являются a ( , а во втором это ( ([0-9].*) ) это число, за которым следуют другие символы.

Ответ №3:

Без дополнительного пакета:

 > data.frame(Name=gsub("\(.*\)", "", df$Name),
            RevCode=regmatches(df$Name, regexpr("[[:digit:]] (\,[[:space:]][[:digit:]] )?", df$Name)),
            Type=df$Type)
                 Name    RevCode      Type
1        Urgent Care        0456  Per Case
2         IV Therapy  0260, 0269 Per Visit
3 Oncology Treatment  0280, 0289 Per Visit