2016-01-08 8 views
2

Учитывая список из 16 элементов, где каждый элемент является именованным числовым вектором, я хочу построить длину пересечения имен между каждыми двумя элементами. То есть; пересечение элемента 1 с элементом 2, элемента элемента 3 с элементом 4 и т. д.Запланировать пересечение в каждом из двух элементов списка

Хотя я могу сделать это очень утомительно, с низкой пропускной способностью, мне придется повторить такой анализ, поэтому Я бы хотел более программный способ сделать это.

В качестве примера, первые 5 записей первых 2 элементов списка являются:

topGenes[[1]][1:5] 

3398 284353 219293  7450 54658 
2.856363 2.654106 2.653845 2.635599 2.626518 

topGenes[[2]][1:5] 
1300 64581  2566  5026 146433 
2.932803 2.807381 2.790484 2.739735 2.705030 

Здесь первая строка чисел идентификаторы генов & Я хочу знать, сколько каждая пара векторов (а лечение повторности) имеют в общем, в том числе, скажем, топ 100.

Я попытался с помощью lapply() следующим образом:

vectorOfIntersectLengths <- lapply(topGenes, function(x) lapply(topGenes, function(y) length(intersect(names(x)[1:100],names(y)[1:100])))) 

Это только кажется, о на первых двух элементах; topGenes [[1]] & topGenes [[2]].

Я также пытался сделать это с помощью цикла for(), но я не уверен, как это записать. Что-то вроде этого:

lengths <- c() 
for(i in 1:length(topGenes)){ 
    lens[i] <- length(intersect(names(topGenes[[i]][1:200]), 
names(topGenes[[i+1]][1:200]))) 
} 

Это возвращает ошибку «индекс за пределами границ», которую я действительно не понимаю.

Большое спасибо за помощь!

+0

возможно см. '? Expand.grid', но я не совсем уверен, что вы просите. не могли бы вы предоставить 'dput (topGenes)' или представительный пример подмножества? – C8H10N4O2

+0

Несомненно. Вот первые 10 записей первых двух элементов списка: – Forest

+0

Извините, слишком скоро нажмите «ввести» в ответ. Я редактировал сообщение для (надеюсь) ясности. – Forest

ответ

1

Это вы что искали?

# make some fake data 
set.seed(123) 
some_list <- lapply(1:16, function(x) { 
    y <- rexp(100) 
    names(y) <- sample.int(1000,100) 
    y 
}) 

# identify all possible pairs 
pairs <- t(combn(length(some_list), 2)) 
# note: you could also use: pairs <- expand.grid(1:length(some_list),1:length(some_list)) 
# but in addition to a-to-b, you'd get b-to-a, a-to-a, and b-to-b 

# get the intersection of names of a pair of elements with given indices kept for bookkeeping 
get_intersection <- function(a,b) { 
    list(a = a, b = b, 
     intersection = intersect(names(some_list[[a]]), names(some_list[[b]])) 
) 
} 

# get intersection for each pair 
intersections <- mapply(get_intersection, a = pairs[,1], b = pairs[,2], SIMPLIFY=FALSE) 

# print the intersections 
for(indx in 1:length(intersections)){ 
    writeLines(paste('Intersection of', intersections[[indx]]$a, 'and', 
        intersections[[indx]]$b, 'contains:', 
        paste(sort(intersections[[indx]]$intersection), collapse=', '))) 
} 
+0

Почти! Я вижу пересекающиеся длины в результирующем векторе вместе с самопересечениями. – Forest

+0

@Forest как о как отредактировано? – C8H10N4O2

+0

Он делает. Результат выглядит немного забавным, но имена пересекающихся элементов, которые я ищу, определенно находятся там. Когда я запускаю код, выходные, пересечения выглядят следующим образом: – Forest