基于R dplyr中的数据库提取字符串
Extract strings based on a database in R dplyr
我想从我的数据中提取数据库中 L 和 R 字符串之间的字符串。
我的数据库包含 4 种不同的 L 和 R 字符串组合,我想测试所有这些组合。
一种方法是写一个for循环,但是有没有更优雅更巧妙的方法呢?
library(tidyverse)
data <- c("CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA",
"CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA",
"CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCAGCGCCAACCAGATAAGTGGAATCTAGTTCGA",
"CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA") %>%
as.data.frame() %>%
rename(seq=1)
database=data.frame(L=c("CTACG","CTAGG","CTCCG"), R=c("CAGTC","CAGTC","CAGTC"))
data %>%
mutate(extracts= str_extract(.$seq,
str_c("(?<=",str_c(database[1,1], collapse = ""),").*(?=",str_c(database[1,2], collapse = ""),")")))
#> seq
#> 1 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 2 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 3 CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCAGCGCCAACCAGATAAGTGGAATCTAGTTCGA
#> 4 CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> extracts
#> 1 TACGGTTATATTGACAGACCGAGGG
#> 2 TACGGTTATATTGACAGACCGAGGG
#> 3 <NA>
#> 4 <NA>
由 reprex package (v2.0.1)
创建于 2022-02-01
我会创建您独特的模式,然后应用到它们身上。然后,您可以 cbind
使用原始数据框获得结果。
library(stringr)
patterns <- paste0(database$L, "(.*)", database$R)
names(patterns) <- paste0("pattern", 1:3)
cbind(
data,
lapply(
patterns,
\(x) str_match(data$seq, x)[,2]
)
)
#> seq
#> 1 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 2 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 3 CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCAGCGCCAACCAGATAAGTGGAATCTAGTTCGA
#> 4 CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> pattern1 pattern2 pattern3
#> 1 TACGGTTATATTGACAGACCGAGGG <NA> <NA>
#> 2 TACGGTTATATTGACAGACCGAGGG <NA> <NA>
#> 3 <NA> GGGGGGCTATTTTGGACTGCGTTAC <NA>
#> 4 <NA> <NA> TGCGGTTATATTGACAGACCGAGGG
这只会捕获第一个匹配项。如果您需要捕获其他匹配项,可能会变得更复杂一些。我认为最简单的方法是生成您要检查的模式和序列的所有唯一组合,然后在 mutate()
中创建一个列表列。在这种情况下,我们可以使用您原来的 lookaheads/behinds 并使用 str_extract_all()
.
library(dplyr)
library(tidyr)
patterns <- paste0("(?<=", database$L, ")(.*)(?=", database$R, ")")
names(patterns) <- paste0("pattern", 1:3)
expand_grid(seq = data$seq,
pattern = patterns) %>%
distinct() %>%
mutate(match = str_extract_all(seq, pattern)) %>%
pivot_wider(
names_from = "pattern",
values_from = "match"
) %>%
rename_with(~names(patterns),
.cols = -seq)
#> # A tibble: 3 × 4
#> seq pattern1 pattern2 pattern3
#> <chr> <list> <list> <list>
#> 1 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCA… <chr> <chr> <chr>
#> 2 CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCA… <chr> <chr> <chr>
#> 3 CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCA… <chr> <chr> <chr>
我想从我的数据中提取数据库中 L 和 R 字符串之间的字符串。
我的数据库包含 4 种不同的 L 和 R 字符串组合,我想测试所有这些组合。
一种方法是写一个for循环,但是有没有更优雅更巧妙的方法呢?
library(tidyverse)
data <- c("CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA",
"CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA",
"CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCAGCGCCAACCAGATAAGTGGAATCTAGTTCGA",
"CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA") %>%
as.data.frame() %>%
rename(seq=1)
database=data.frame(L=c("CTACG","CTAGG","CTCCG"), R=c("CAGTC","CAGTC","CAGTC"))
data %>%
mutate(extracts= str_extract(.$seq,
str_c("(?<=",str_c(database[1,1], collapse = ""),").*(?=",str_c(database[1,2], collapse = ""),")")))
#> seq
#> 1 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 2 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 3 CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCAGCGCCAACCAGATAAGTGGAATCTAGTTCGA
#> 4 CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> extracts
#> 1 TACGGTTATATTGACAGACCGAGGG
#> 2 TACGGTTATATTGACAGACCGAGGG
#> 3 <NA>
#> 4 <NA>
由 reprex package (v2.0.1)
创建于 2022-02-01我会创建您独特的模式,然后应用到它们身上。然后,您可以 cbind
使用原始数据框获得结果。
library(stringr)
patterns <- paste0(database$L, "(.*)", database$R)
names(patterns) <- paste0("pattern", 1:3)
cbind(
data,
lapply(
patterns,
\(x) str_match(data$seq, x)[,2]
)
)
#> seq
#> 1 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 2 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> 3 CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCAGCGCCAACCAGATAAGTGGAATCTAGTTCGA
#> 4 CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCAGCGCCAACCAGATAAGTGAAATCTAGTTCCA
#> pattern1 pattern2 pattern3
#> 1 TACGGTTATATTGACAGACCGAGGG <NA> <NA>
#> 2 TACGGTTATATTGACAGACCGAGGG <NA> <NA>
#> 3 <NA> GGGGGGCTATTTTGGACTGCGTTAC <NA>
#> 4 <NA> <NA> TGCGGTTATATTGACAGACCGAGGG
这只会捕获第一个匹配项。如果您需要捕获其他匹配项,可能会变得更复杂一些。我认为最简单的方法是生成您要检查的模式和序列的所有唯一组合,然后在 mutate()
中创建一个列表列。在这种情况下,我们可以使用您原来的 lookaheads/behinds 并使用 str_extract_all()
.
library(dplyr)
library(tidyr)
patterns <- paste0("(?<=", database$L, ")(.*)(?=", database$R, ")")
names(patterns) <- paste0("pattern", 1:3)
expand_grid(seq = data$seq,
pattern = patterns) %>%
distinct() %>%
mutate(match = str_extract_all(seq, pattern)) %>%
pivot_wider(
names_from = "pattern",
values_from = "match"
) %>%
rename_with(~names(patterns),
.cols = -seq)
#> # A tibble: 3 × 4
#> seq pattern1 pattern2 pattern3
#> <chr> <list> <list> <list>
#> 1 CCACGAAGCTCTCCTACGTACGGTTATATTGACAGACCGAGGGCAGTCCA… <chr> <chr> <chr>
#> 2 CCACGAAGCTCTCCTAGGGGGGGGCTATTTTGGACTGCGTTACCAGTCCA… <chr> <chr> <chr>
#> 3 CCACGTAGCTCTCCTCCGTGCGGTTATATTGACAGACCGAGGGCAGTCCA… <chr> <chr> <chr>