Я предоставил два решения, используя два разных пакета с возможностями диаграммы Венна. Как вы и ожидали, оба включают начальный шаг с использованием функции aggregate()
.
Я предпочитаю результаты из пакета venneuler
. Положение меток по умолчанию не является идеальным, но вы можете изменить их, посмотрев на связанный метод plot
(возможно, используя locator()
для выбора координат).
Решение 1-е:
Одна из возможностей - использовать venneuler()
в пакете venneuler
, чтобы нарисовать диаграмму Венна.
library(venneuler)
## Modify the "factor" column, by renaming it and converting
## it to a character vector.
levels(data$factor) <- c("a", "b", "c")
data$factor <- as.character(data$factor)
## FUN is an anonymous function that determines which letters are present
## 2 or more times in the cluster and then pastes them together into
## strings of a form that venneuler() expects.
##
inter <- aggregate(factor ~ cluster, data=data,
FUN = function(X) {
tab <- table(X)
names <- names(tab[tab>=2])
paste(sort(names), collapse="&")
})
## Count how many clusters contain each combination of letters
counts <- table(inter$factor)
counts <- counts[names(counts)!=""] # To remove groups with <2 of any letter
# a a&b a&b&c a&c b b&c c
# 19 13 12 14 13 9 12
## Convert to proportions for venneuler()
ps <- counts/sum(counts)
## Calculate the Venn diagram
vd <- venneuler(c(a=ps[["a"]], b = ps[["b"]], c = ps[["c"]],
"a&b" = ps[["a&b"]],
"a&c" = ps[["a&c"]],
"b&c" = ps[["b&c"]],
"a&b&c" = ps[["a&b&c"]]))
## Plot it!
plot(vd)
Несколько замечаний о выборе, который я сделал при написании этого кода:
Я изменил названия факторов с "factor-a"
на "a"
. Вы можете изменить это обратно.
Я только требовал, чтобы каждый фактор присутствовал> = 2 раза (вместо> 10) для подсчета в каждом кластере. (Это должно было продемонстрировать код с этим небольшим подмножеством ваших данных.)
Если вы посмотрите на промежуточный объект counts
, вы увидите, что он содержит начальный безымянный элемент. Этот элемент представляет собой количество кластеров, которые содержат менее 2 любой буквы. Вы можете лучше, чем я, решить, хотите ли вы включить их в расчет последующего объекта ps
(«пропорции»).
Решение 2-е:
Другая возможность - использовать vennCounts()
и vennDiagram()
в пакете Bioconductor limma
. Чтобы загрузить пакет, следуйте приведенным здесь инструкциям. В отличие от решения venneuler
, приведенного выше, перекрытие в результирующей диаграмме не пропорционально фактической степени пересечения. Вместо этого он аннотирует диаграмму фактическими частотами. (Обратите внимание, что это решение не требует внесения изменений в столбец data$factor
.)
library(limma)
out <- aggregate(factor ~ cluster, data=data, FUN=table)
out <- cbind(out[1], data.frame(out[2][[1]]))
counts <- vennCounts(out[, -1] >= 2)
vennDiagram(counts, names = c("Factor A", "Factor B", "Factor C"),
cex = 1, counts.col = "red")