У меня есть вектор A, который содержит список родов, которые я хочу использовать для подмножества второго вектора, B. Я успешно использовал grepl для извлечения из B чего-либо, что частично соответствует родам в A. Ниже воспроизводимый пример того, что я сделал.

Но теперь я хотел бы получить список, какие роды в A совпадают с чем-то в B, а какие нет. Т.е. «сопоставленный» список будет содержать Cortinarius и Russula, а «несогласованный» список будет содержать Laccaria и Inocybe. Есть идеи, как это сделать? На самом деле мои векторы очень длинные, и названия родов в B не находятся в одном положении среди другой информации.

# create some dummy vectors
A <- c("Cortinarius","Laccaria","Inocybe","Russula")
B <- c("fafsdf_Cortinarius_sdfsdf","sdfsdf_Russula_sdfsdf_fdf","Tomentella_sdfsdf","sdfas_Sebacina","sdfsf_Clavulina_sdfdsf")

# extract the elements of B that have a partial match to anything in A.
new.B <- B[grepl(paste(A,collapse="|"), B)]

# But now how do I tell which elements of A were present in B, and which ones were not?
1
LvG 25 Сен 2021 в 03:03

2 ответа

Лучший ответ

Мы могли бы использовать lapply или sapply для перебора шаблонов и затем получить именованный вывод

out <- setNames(lapply(A, function(x) grep(x, B, value = TRUE)), A)

Тогда легче проверить те, которые возвращают пустые элементы

> out[lengths(out) > 0]
$Cortinarius
[1] "fafsdf_Cortinarius_sdfsdf"

$Russula
[1] "sdfsdf_Russula_sdfsdf_fdf"

> out[lengths(out) == 0]
$Laccaria
character(0)

$Inocybe
character(0)

И получите names этого

> names(out[lengths(out) > 0])
[1] "Cortinarius" "Russula"    
> names(out[lengths(out) == 0])
[1] "Laccaria" "Inocybe" 
2
akrun 25 Сен 2021 в 00:04

Вы можете использовать sapply с grepl для проверки соответствия каждого значения A с любым значением B.

sapply(A, grepl, B)

#     Cortinarius Laccaria Inocybe Russula
#[1,]        TRUE    FALSE   FALSE   FALSE
#[2,]       FALSE    FALSE   FALSE    TRUE
#[3,]       FALSE    FALSE   FALSE   FALSE
#[4,]       FALSE    FALSE   FALSE   FALSE
#[5,]       FALSE    FALSE   FALSE   FALSE

Вы можете взять сумму этих значений по столбцам, чтобы получить количество совпадений.

result <- colSums(sapply(A, grepl, B))
result

#Cortinarius    Laccaria     Inocybe     Russula 
#          1           0           0           1 

#values with at least one match
names(Filter(function(x) x > 0, result))
#[1] "Cortinarius" "Russula" 

#values with no match
names(Filter(function(x) x == 0, result))
#[1] "Laccaria" "Inocybe" 
0
Ronak Shah 25 Сен 2021 в 03:46