来自集群和共现因素列表的维恩图

Posted

技术标签:

【中文标题】来自集群和共现因素列表的维恩图【英文标题】:Venn diagram from list of clusters and co-occurring factors 【发布时间】:2011-12-30 12:22:17 【问题描述】:

我有一个输入文件,其中包含约 50000 个集群的列表,并且每个集群中都存在许多因素(总共约 1000 万个条目),请参见下面的较小示例:

set.seed(1)
x = paste("cluster-",sample(c(1:100),500,replace=TRUE),sep="")
y = c(
  paste("factor-",sample(c(letters[1:3]),300, replace=TRUE),sep=""),
  paste("factor-",sample(c(letters[1]),100, replace=TRUE),sep=""),
  paste("factor-",sample(c(letters[2]),50, replace=TRUE),sep=""),
  paste("factor-",sample(c(letters[3]),50, replace=TRUE),sep="")
)
data = data.frame(cluster=x,factor=y)

在另一个问题的帮助下,我得到了一个饼图,用于同时出现这样的因素:

counts = with(data, table(tapply(factor, cluster, function(x) paste(as.character(sort(unique(x))), collapse='+'))))
pie(counts[counts>1])

但是现在我想要一个维恩图来表示因素的共现。理想情况下,也可以采用每个因素的最小计数阈值的方式。例如,不同因素的维恩图,这样每个因素都必须在每个集群中出现 n>10 才能被考虑在内。

我试图找到一种方法来使用聚合生成表计数,但无法使其工作。

【问题讨论】:

你看过任何用于维恩图的 R 包吗?请参阅 G. Jay Kerns 使用 venneuler 库的 this recent example,或使用 venn 库 (Murdoch, 2004) 在 Stat Software 杂志上的这篇简短文章。如果这纯粹是关于 R 编程,它应该迁移到 SO。 Avilella,这个问题可能没有得到任何答案,因为它有点偏离主题。你可能会在 SO 上做得更好,它有一个活跃的 R 用户社区。但请不要交叉发布:如果您希望迁移该问题,只需标记问题以引起版主注意。 我标记了它,但我还看不到它被移动到 SO... 嗯...没有引发标志。我来这里只是因为我记得。无论如何,我们走吧。我相信您会在 SO 上得到一些好的答复。 @avilella -- 以下解决方案是否符合要求?如果您有另一个维恩图包,并且无法将数据转换为适当的形式,请告诉我。谢谢。 【参考方案1】:

我提供了两个解决方案,使用两个具有维恩图功能的不同包。如您所料,两者都涉及使用aggregate() 函数的初始步骤。

我更喜欢 venneuler 包中的结果。它的默认标签位置并不理想,但您可以通过查看关联的plot 方法来调整它们(可能使用locator() 来选择坐标)。

解决方法一:

一种可能性是使用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 ('proportions') 对象的计算中。

解决方案二:

另一种可能性是在 Bioconductor 包limma 中使用vennCounts()vennDiagram()。要下载包,follow the instructions here. 与上面的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")

【讨论】:

以上是关于来自集群和共现因素列表的维恩图的主要内容,如果未能解决你的问题,请参考以下文章

R 中的维恩图 - 提取每个维恩区域的元素,甚至使其具有交互性

来自嵌套单词列表的共现矩阵

基本维恩图在哪个位置

从共现矩阵中提取纹理特征

如何创建维恩图,用这个工具就可以了!

在wps中如何画维恩图