#r #matrix #vector
#r #матрица #вектор
Вопрос:
У меня есть 3 вектора, содержащих более 1500 элементов символьной строки, которые я хочу попарно сравнить для вывода количества совпадающих элементов между ними.
Уменьшенный объем моих данных:
va <- c("6a460daf68eb0410b51d79e495fbccc7", "e1b32017108e17e41bdabc44bac4df3c", "6ac1327da92d8584008db04b4eaf62d0", "b01a2322e2ca99315646d79cf157cb20", "12dadc27059ea5d3c8cc54e9a28cc4f6", "be73c9685b743a646f2eb0480eee2f8d")
vb <- c("6a460daf68eb0410b51d79e495fbccc7", "e1b32017108e17e41bdabc44bac4df3c","JQ183785.1.1345", "DQ794886.1.1390", "HQ791014.1.1450", "EU764755.1.1328")
vc <- c("6a460daf68eb0410b51d79e495fbccc7", "JQ183785.1.1345", "DQ794886.1.1390", "HQ791014.1.1450", "b01a2322e2ca99315646d79cf157cb20", "EF532786.1.1364")
Я создал функцию для вывода количества совпадающих элементов между двумя векторами:
sharing <- function(v1, v2, share=TRUE){
if(isTRUE(share)){sh <- length(v1[ v1 %in% v2])}
else if (isFALSE(share)){sh <- length(v1[ ! v1 %in% v2])}
return(sh)
}
Итак, применив эту функцию 9 раз (по одному для каждого попарного сравнения, включая самосравнение), я смог бы получить 9 чисел с общими элементами:
> sharing(va,va); sharing(va,vb); sharing(va,vc)
[1] 6
[1] 2
[1] 2
> sharing(vb,va); sharing(vb,vb); sharing(vb,vc)
[1] 2
[1] 6
[1] 4
> sharing(vc,va); sharing(vc,vb); sharing(vc,vc)
[1] 2
[1] 4
[1] 6
Но я хотел бы получить это как матрицу:
va vb vc
va 6 2 2
vb 2 6 4
vc 2 4 6
Есть ли какая-либо готовая функция или код, который может это сделать?
Спасибо за помощь!
Ответ №1:
Одним из вариантов является outer
применение sharing
функции к попарной комбинации vector
s в list
(‘lst1’)
lst1 <- mget(paste0("v", letters[1:3])) # placed the vectors in a list
out <- outer(lst1, lst1, FUN = Vectorize(sharing)) #apply the sharing
dimnames(out) <- list(names(lst1), names(lst1)) # set the dim names