从 data.table R 中的字符变量中提取数值和字符值
Extract numeric and character values from a character variable in data.table 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
。省时的功能很棒。
也许你可以像下面那样尝试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
在第一个数字之前插入一个 @
(或任何其他不在您的列中的字符),然后使用它将列分成两列:
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)]
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
虽然不是这个方法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
我有以下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
。省时的功能很棒。
也许你可以像下面那样尝试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
在第一个数字之前插入一个 @
(或任何其他不在您的列中的字符),然后使用它将列分成两列:
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)]
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
虽然不是这个方法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