Извлекать числовые и символьные значения из символьной переменной в data.table R

#r #data.table #character #extract #numeric

#r #данные.таблица #символ #извлекать #числовые

Вопрос:

У меня есть следующее data.table

 df <- data.table(id=c(1,2,3,4),
                 medication=c("Abc de 3 MG", "Afg frt re 4 MG/ML","Agh","Aj yr 5 MG"))
  

с помощью

 id         medication
1:  1        Abc de 3 MG
2:  2 Afg frt re 4 MG/ML
3:  3                Agh
4:  4         Aj yr 5 MG
  

Я хочу извлечь дозы из лекарства и создать столбец с именем doses

 id medication   doses
1:  1     Abc de    3 MG
2:  2 Afg frt re 4 MG/ML
3:  3        Agh    <NA>
4:  4      Aj yr    5 MG
  

Она должна содержать число и единицу измерения. Не у каждого лекарства есть номер и единица измерения, которые следует указывать как NA .

Я просмотрел tidyverse extract функцию, но не смог найти что-либо для извлечения numeric и character значений. Я использую data.table с большим набором данных. Отличная функция, экономящая время.

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

1. df[,doses := sub(".*(\d.*)|.*","\1",medication)] ??

Ответ №1:

Вставьте @ (или любой другой символ, которого еще нет в вашем столбце) перед первым числом, затем используйте его для разделения столбца на два:

 df[, c("medication", "doses") := tstrsplit(sub("([0-9])", "@\1", medication), "@")]
df

#    id  medication   doses
# 1:  1     Abc de     3 MG
# 2:  2 Afg frt re  4 MG/ML
# 3:  3         Agh    <NA>
# 4:  4      Aj yr     5 MG
  

Редактировать

Чистым решением является использование немного более продвинутого регулярного выражения (позитивный прогноз), просто нужно помнить perl = TRUE :

 df[, c("medication", "doses") := tstrsplit(medication, ".(?=[0-9])", perl = TRUE)]
  

Ответ №2:

Может быть, вы можете попробовать strsplit , как показано ниже

 df[-1] <- do.call(rbind,lapply(strsplit(df$medication,"(?<=[A-Za-z])\s(?=[0-9])",perl = TRUE),`length<-`,2))
  

что дает

 > df
  id medication.1 medication.2
1  1       Abc de         3 MG
2  2   Afg frt re      4 MG/ML
3  3          Agh         <NA>
4  4        Aj yr         5 MG
  

Ответ №3:

Опция с extract из tidyr

 library(tidyr)
extract(df, medication, into = c('medication', 'doses'), '(.*)\s (\d \s \D )$')
#   id medication   doses
#1:  1     Abc de    3 MG
#2:  2 Afg frt re 4 MG/ML
#3:  3       <NA>    <NA>
#4:  4      Aj yr    5 MG
  

Ответ №4:

Хотя этот метод не является data.table, но вы можете принять его во внимание

 library(tidyr)
df %>% 
  separate(medication, into = c("medication", "doses"), sep = "(?=\d)")
# id  medication   doses
# 1  1     Abc de     3 MG
# 2  2 Afg frt re  4 MG/ML
# 3  3         Agh    <NA>
# 4  4      Aj yr     5 MG