使用 R 中的正则表达式(grepl 函数)从数据列中提取多个所需模式的正确方法是什么
What is the correct way to extract multiple required patterns from a column in the data using regular expression (grepl function) in R
我有一个数据框(也可以使用我生成的 CSV 文件),它有 7 列和近一百万行。
我特别感兴趣的是从单个列中存在的整个数据字符串中获取 5 个不同的 "ID's",并希望创建具有特定 "ID" 作为列 [=43] 的新列=] name.The 数据看起来像这样 -
UNIQUE-NAME TYPES COMMON-NAME FORMULA SOURCE WEIGHT SECONDARY-WEIGHT
CPD-12676 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) (SPIDER "3315400" NIL | devarsh | 3468 NIL);(PUBCHEM "54758713" NIL | ong);(SMALL "35022" | NIL | Tom);(CHEBI "28643" | NIL);(BAS "55672-34-1" | Harry | NILL) 29.83 27.65
CPD-380 Enamines UDP NA NA 294.37 287.33
NAD Steroids prephenate (O 4);(S 1) (PUBCHEM "87361293" NIL | ong);(CHEBI "87100" | NIL); (BAS "91234-28-2" | Harry | NILL) 373.47 381.24
ADP Rings pyridine (C 5);(H 5);(N 1) (SPIDER "2311345" NIL | devarsh | 6789 NIL);(SMALL "98234" | NIL | Tom) 39.33 40.65
CAD-392 Molecules pyrine (C 10);(H 9) (SPIDER "5454678" NIL | devarsh | 7688 NIL) 392.543 400.656
CAD-355 Groups solution (C 12);(H 12) NA 32.53 40.66
CPD-39234 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) (SMALL "45465" | NIL | Harry);(CHEBI "33490" | NIL) 92.43 100.65
现在我对 "SOURCE" 列感兴趣并想获取
SPIDER ID, PUBCHEM ID, SMALL ID, CHEBI ID AND BAS ID
并在我的 csv 文件中创建一个新列,其中每个 ID 作为列 headers,并将 ID 号存储为行。
所以,我希望我的最终输出 table 是这样的 -
UNIQUE-NAME TYPES COMMON-NAME FORMULA SMALL ID PUBCHEM ID SPIDER ID CHEBI ID BAS ID WEIGHT SECONDARY-WEIGHT
CPD-12676 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 35022 54758713 3315400 28643 55672-34-1 29.83 27.65
CPD-380 Enamines UDP NA NA NA NA NA NA 294.37 287.33
NAD Steroids prephenate (O 4);(S NA 87361293 NA 87100 91234-28-2 373.47 381.24
ADP Rings pyridine (C 5);(H 5);(N 1) 98234 NA 2311345 NA NA 39.33 40.65
CAD-392 Molecules pyrine (C 10);(H 9) NA NA 5454678 NA NA 392.543 400.656
CAD-355 Groups solution (C 12);(H 12) NA NA NA NA NA 32.53 40.66
CPD-39234 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 45465 NA NA 33490 NA 92.43 100.65
我使用 grepl
函数来实现这个结果 -
dt3 <- grepl("^[:punct:]SMALL\s[:punct:][0-9][:punct:]|^[:punct:]SPIDER\s[:punct:][0-9][:punct:]|[:punct:]BAS\s[:punct:][0-9]-+[:punct:]|[:punct:]CHEBI\s[:punct:][0-9][:punct:]|[:punct:]PUBCHEM\s[:punct:][0-9][:punct:]", dt2$SOURCE)
其中 dt2
是包含数据的数据帧(显示在上面的第一个 table 中)。我只使用 SOURCE
列并尝试匹配我想要获取的列的模式。 grepl
没有抛出任何错误,但给出了所有 FALSE
值,这显然意味着我在此处使用正则表达式语法进行模式匹配时做错了,并且 R
不理解我想要获取的内容。
非常感谢您对此的帮助。谢谢!
示例源数据 - Sample data
尝试将您的问题缩小到您需要的最小示例。例如,数据框的 SOURCE
列包含您想要匹配正则表达式的字符串:
SOURCE <- '(SPIDER "3315400" NIL | devarsh | 3468 NIL);(PUBCHEM "54758713" NIL | ong)'
您可以使用括号 ()
提取成组的内容,其中每个括号都是一个新组,并且您可以在另一个组中包含一个组:
pattern <- "((PUBCHEM) \"([0-9]*))"
regmatches(SOURCE, regexec(pattern, SOURCE))
给你一个包含 4 个字符串的向量,每个字符串对应一个组。向量元素 3 和 4 持有 PUBCHEM
AND 54758713
.
这里是使用dplyr
和stringr
的非常粗略的方法。
library(dplyr)
library(stringr)
df %>% # this assumes your data is in a data frame called 'df'
mutate(small_id = str_extract(SOURCE, 'SMALL "[0-9]+"')) %>%
mutate(pubchem_id = str_extract(SOURCE, 'PUBCHEM "[0-9]+"')) %>%
mutate(spider_id = str_extract(SOURCE, 'SPIDER "[0-9]+"')) %>%
mutate(chebi_id = str_extract(SOURCE, 'CHEBI "[0-9]+"')) %>%
mutate(bas_id = str_extract(SOURCE, 'BAS "[0-9]+-[0-9]+-[0-9]+"')) %>%
mutate_at(vars(ends_with('_id')), ~gsub('[A-Z]|"|\s+', '', .)) %>%
select(-SOURCE)
`UNIQUE-NAME` TYPES `COMMON-NAME` FORMULA WEIGHT `SECONDARY-WEIGHT` small_id pubchem_id spider_id chebi_id bas_id
<chr> <chr> <chr> <chr> <dbl> <dbl> <chr> <chr> <chr> <chr> <chr>
1 CPD-12676 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 29.8 27.6 35022 54758713 3315400 28643 55672-34-1
2 CPD-380 Enamines UDP NA 294. 287. NA NA NA NA NA
3 NAD Steroids prephenate (O 4);(S 1) 373. 381. NA 87361293 NA 87100 91234-28-2
4 ADP Rings pyridine (C 5);(H 5);(N 1) 39.3 40.6 98234 NA 2311345 NA NA
5 CAD-392 Molecules pyrine (C 10);(H 9) 393. 401. NA NA 5454678 NA NA
6 CAD-355 Groups solution (C 12);(H 12) 32.5 40.7 NA NA NA NA NA
7 CPD-39234 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 92.4 101. 45465 NA NA 33490 NA
我有一个数据框(也可以使用我生成的 CSV 文件),它有 7 列和近一百万行。
我特别感兴趣的是从单个列中存在的整个数据字符串中获取 5 个不同的 "ID's",并希望创建具有特定 "ID" 作为列 [=43] 的新列=] name.The 数据看起来像这样 -
UNIQUE-NAME TYPES COMMON-NAME FORMULA SOURCE WEIGHT SECONDARY-WEIGHT
CPD-12676 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) (SPIDER "3315400" NIL | devarsh | 3468 NIL);(PUBCHEM "54758713" NIL | ong);(SMALL "35022" | NIL | Tom);(CHEBI "28643" | NIL);(BAS "55672-34-1" | Harry | NILL) 29.83 27.65
CPD-380 Enamines UDP NA NA 294.37 287.33
NAD Steroids prephenate (O 4);(S 1) (PUBCHEM "87361293" NIL | ong);(CHEBI "87100" | NIL); (BAS "91234-28-2" | Harry | NILL) 373.47 381.24
ADP Rings pyridine (C 5);(H 5);(N 1) (SPIDER "2311345" NIL | devarsh | 6789 NIL);(SMALL "98234" | NIL | Tom) 39.33 40.65
CAD-392 Molecules pyrine (C 10);(H 9) (SPIDER "5454678" NIL | devarsh | 7688 NIL) 392.543 400.656
CAD-355 Groups solution (C 12);(H 12) NA 32.53 40.66
CPD-39234 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) (SMALL "45465" | NIL | Harry);(CHEBI "33490" | NIL) 92.43 100.65
现在我对 "SOURCE" 列感兴趣并想获取
SPIDER ID, PUBCHEM ID, SMALL ID, CHEBI ID AND BAS ID
并在我的 csv 文件中创建一个新列,其中每个 ID 作为列 headers,并将 ID 号存储为行。
所以,我希望我的最终输出 table 是这样的 -
UNIQUE-NAME TYPES COMMON-NAME FORMULA SMALL ID PUBCHEM ID SPIDER ID CHEBI ID BAS ID WEIGHT SECONDARY-WEIGHT
CPD-12676 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 35022 54758713 3315400 28643 55672-34-1 29.83 27.65
CPD-380 Enamines UDP NA NA NA NA NA NA 294.37 287.33
NAD Steroids prephenate (O 4);(S NA 87361293 NA 87100 91234-28-2 373.47 381.24
ADP Rings pyridine (C 5);(H 5);(N 1) 98234 NA 2311345 NA NA 39.33 40.65
CAD-392 Molecules pyrine (C 10);(H 9) NA NA 5454678 NA NA 392.543 400.656
CAD-355 Groups solution (C 12);(H 12) NA NA NA NA NA 32.53 40.66
CPD-39234 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 45465 NA NA 33490 NA 92.43 100.65
我使用 grepl
函数来实现这个结果 -
dt3 <- grepl("^[:punct:]SMALL\s[:punct:][0-9][:punct:]|^[:punct:]SPIDER\s[:punct:][0-9][:punct:]|[:punct:]BAS\s[:punct:][0-9]-+[:punct:]|[:punct:]CHEBI\s[:punct:][0-9][:punct:]|[:punct:]PUBCHEM\s[:punct:][0-9][:punct:]", dt2$SOURCE)
其中 dt2
是包含数据的数据帧(显示在上面的第一个 table 中)。我只使用 SOURCE
列并尝试匹配我想要获取的列的模式。 grepl
没有抛出任何错误,但给出了所有 FALSE
值,这显然意味着我在此处使用正则表达式语法进行模式匹配时做错了,并且 R
不理解我想要获取的内容。
非常感谢您对此的帮助。谢谢!
示例源数据 - Sample data
尝试将您的问题缩小到您需要的最小示例。例如,数据框的 SOURCE
列包含您想要匹配正则表达式的字符串:
SOURCE <- '(SPIDER "3315400" NIL | devarsh | 3468 NIL);(PUBCHEM "54758713" NIL | ong)'
您可以使用括号 ()
提取成组的内容,其中每个括号都是一个新组,并且您可以在另一个组中包含一个组:
pattern <- "((PUBCHEM) \"([0-9]*))"
regmatches(SOURCE, regexec(pattern, SOURCE))
给你一个包含 4 个字符串的向量,每个字符串对应一个组。向量元素 3 和 4 持有 PUBCHEM
AND 54758713
.
这里是使用dplyr
和stringr
的非常粗略的方法。
library(dplyr)
library(stringr)
df %>% # this assumes your data is in a data frame called 'df'
mutate(small_id = str_extract(SOURCE, 'SMALL "[0-9]+"')) %>%
mutate(pubchem_id = str_extract(SOURCE, 'PUBCHEM "[0-9]+"')) %>%
mutate(spider_id = str_extract(SOURCE, 'SPIDER "[0-9]+"')) %>%
mutate(chebi_id = str_extract(SOURCE, 'CHEBI "[0-9]+"')) %>%
mutate(bas_id = str_extract(SOURCE, 'BAS "[0-9]+-[0-9]+-[0-9]+"')) %>%
mutate_at(vars(ends_with('_id')), ~gsub('[A-Z]|"|\s+', '', .)) %>%
select(-SOURCE)
`UNIQUE-NAME` TYPES `COMMON-NAME` FORMULA WEIGHT `SECONDARY-WEIGHT` small_id pubchem_id spider_id chebi_id bas_id
<chr> <chr> <chr> <chr> <dbl> <dbl> <chr> <chr> <chr> <chr> <chr>
1 CPD-12676 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 29.8 27.6 35022 54758713 3315400 28643 55672-34-1
2 CPD-380 Enamines UDP NA 294. 287. NA NA NA NA NA
3 NAD Steroids prephenate (O 4);(S 1) 373. 381. NA 87361293 NA 87100 91234-28-2
4 ADP Rings pyridine (C 5);(H 5);(N 1) 39.3 40.6 98234 NA 2311345 NA NA
5 CAD-392 Molecules pyrine (C 10);(H 9) 393. 401. NA NA 5454678 NA NA
6 CAD-355 Groups solution (C 12);(H 12) 32.5 40.7 NA NA NA NA NA
7 CPD-39234 Compounds glycerophosphoglycerol (C 19);(H 29);(N 5);(O 10);(S 2) 92.4 101. 45465 NA NA 33490 NA