У меня есть список с несколькими векторами, который выглядит так:
$`56`
[1] "OTU2998" "UniRef90_A0A1Z9FS94" "UniRef90_A0A257ESC3"
[4] "UniRef90_A0A293NAV3" "UniRef90_A0A2E1NMU8" "UniRef90_A0A2E1NPX9"
[7] "UniRef90_A0A2E1NQL1" "UniRef90_A0A2E1NRD2" "UniRef90_X0UC66"
$`57`
[1] "OTU3820" "UniRef90_A0A1Z9H3N2" "UniRef90_A0A2D5I161"
[4] "UniRef90_A0A2E6PRN5"
$`58`
[1] "OTU4452" "UniRef90_A0A1Z9KBI8" "UniRef90_A0A2E1VTI6"
[4] "UniRef90_A0A2G2KCN6" "UniRef90_UPI000BFEC744"
$`59`
[1] "OTU0245" "UniRef90_A0A1Z9MPM9" "UniRef90_A0A2E2ME98"
[4] "UniRef90_A0A2E8X9N7"
Есть ли способ извлечь только информацию «OTUXXX»? Я имею в виду, что я хотел бы получить что-то вроде этого:
$`56`
[1] "OTU2998"
$`57`
[1] "OTU3820"
$`58`
[1] "OTU4452"
$`59`
[1] "OTU0245"
Мы можем перебрать list
и извлечь элементы, соответствующие подстроке «OTU» в начале (^
) строки, за которыми следуют четыре цифры (\\d{4}
) до конца ($
) строки с grepl
lapply(lst1, function(x) x[grepl("^OTU\\d{4}$", x)])
#$`56`
#[1] "OTU2998"
#$`57`
#[1] "OTU3820"
#$`58`
#[1] "OTU4452"
#$`59`
#[1] "OTU0245" "OTU1234"
ПРИМЕЧАНИЕ. Использование только методов base R
Или, если мы поклонник tidyverse, то используйте keep
library(tidyverse)
map(lst1, keep, str_detect, '^OTU\\d{4}$')
lst1 <- list(
`56` = c("OTU2998", "UniRef90_A0A1Z9FS94", "UniRef90_A0A257ESC3", "UniRef90_A0A293NAV3", "UniRef90_A0A2E1NMU8", "UniRef90_A0A2E1NPX9", "UniRef90_A0A2E1NQL1", "UniRef90_A0A2E1NRD2", "UniRef90_X0UC66"),
`57` = c("OTU3820", "UniRef90_A0A1Z9H3N2", "UniRef90_A0A2D5I161", "UniRef90_A0A2E6PRN5"),
`58` = c("OTU4452", "UniRef90_A0A1Z9KBI8", "UniRef90_A0A2E1VTI6", "UniRef90_A0A2G2KCN6", "UniRef90_UPI000BFEC744"),
`59` = c("OTU0245", "UniRef90_A0A1Z9MPM9", "UniRef90_A0A2E2ME98", "UniRef90_A0A2E8X9N7", "OTU1234")
)
Мне нравится семейство функций purrr::map
за простоту передачи функций и аргументов. Два быстрых варианта извлечения этих элементов: grep
с использованием value = T
для возврата совпадающих строк, а не только их индексов, или с stringr::str_subset
, который делает то же самое.
Регулярное выражение здесь соответствует строкам, начинающимся с «OTU», за которыми следует 1 или более цифр до конца.
Оба метода масштабируются для нескольких совпадений одновременно: я добавил элемент «OTU1234» в последний элемент списка, чтобы проиллюстрировать это.
dl <- list(
`56` = c("OTU2998", "UniRef90_A0A1Z9FS94", "UniRef90_A0A257ESC3", "UniRef90_A0A293NAV3", "UniRef90_A0A2E1NMU8", "UniRef90_A0A2E1NPX9", "UniRef90_A0A2E1NQL1", "UniRef90_A0A2E1NRD2", "UniRef90_X0UC66"),
`57` = c("OTU3820", "UniRef90_A0A1Z9H3N2", "UniRef90_A0A2D5I161", "UniRef90_A0A2E6PRN5"),
`58` = c("OTU4452", "UniRef90_A0A1Z9KBI8", "UniRef90_A0A2E1VTI6", "UniRef90_A0A2G2KCN6", "UniRef90_UPI000BFEC744"),
`59` = c("OTU0245", "UniRef90_A0A1Z9MPM9", "UniRef90_A0A2E2ME98", "UniRef90_A0A2E8X9N7", "OTU1234")
)
purrr::map(dl, ~grep("^OTU\\d+$", ., value = T))
#> $`56`
#> [1] "OTU2998"
#>
#> $`57`
#> [1] "OTU3820"
#>
#> $`58`
#> [1] "OTU4452"
#>
#> $`59`
#> [1] "OTU0245" "OTU1234"
purrr::map(dl, stringr::str_subset, "^OTU\\d+$")
# same output as above
На самом деле, в векторе может быть более одного «OTUXXX», и они могут располагаться в векторах случайным образом.