2

我有一个如下所示的数据框:

set.seed(1)
mydf <- data.frame()
for (g in LETTERS[1:4]){
    m <- data.frame(Group=g,
                    Gene=paste(sample(letters[1:4],25,replace=TRUE), sample(1:25,25,replace=FALSE), sep=''),
                    FoldChange=runif(25, -2, 2))
    mydf <- rbind(mydf, m)
}
mydf$UpDown <- "DOWN"
mydf$UpDown[which(mydf$FoldChange>0)] <- "UP"
head(mydf)

  Group Gene  FoldChange UpDown
1     A  b10 -0.08952151   DOWN
2     A   b1  1.44483791     UP
3     A   c9 -0.24761157   DOWN
4     A  d20 -1.02081089   DOWN
5     A   a8 -1.71728381   DOWN
6     A  d25 -1.60213536   DOWN

我想显示 cross 的交集GenesGroups所以我做了一个维恩图:

mylist <- split(as.character(mydf$Gene), list(mydf$Group))
venn.diagram(mylist, filename="test.png", height=1000, width=1000, imagetype="png", units="px")

测试1

但是,我真的很想以某种方式显示FoldChange(或至少是UpDown)值。我想过做这样的事情,将重叠的数字分成UPDOWN Genes

测试2

但是仍然有一个给定Gene的情况可以UP在一个GroupDOWN另一个中,所以上面的维恩图会很不准确......

subset(mydf, Gene=='b16')
   Group Gene FoldChange UpDown
16     A  b16 -0.9679329   DOWN
34     B  b16  0.5711820     UP
90     D  b16 -1.1147763   DOWN

我认为展示这一点的最佳方式是Circos 情节

每个 应该有一个部分Group,链接组之间的共享Genes,并包括FoldChange(或UpDown)信息。

我可以想到两种可以包含信息的方式:

1-Gene如果 A 和 B 之间的连接线(例如)在两者中,则为红色,如果在DOWN两者Groups中,则为蓝色。如果在 A 和B 中,它们会被染成红色变成蓝色,如果发生相反的情况,它们会变成蓝色(这有意义吗?)UPGroupsGeneDOWNUP

2-在 Circos 图中包含一条额外的信息带,其中包含FoldChange值(红色表示负条,蓝色表示正条)。Genes重叠的大部分都在一起会很好(而不是到处都是细毛,并根据FoldChange值排序)。可能与此类似: 测试3

但是,我真的不知道如何开始,我过去尝试使用该circlize软件包制作简单的 Circos 图,但完全失败了。

我认为我想要完成的概念相当简单......有没有人知道如何在 Circos 图上清楚地显示它(或者就此而言,你可以建议的任何其他表示)?

非常感谢!

4

1 回答 1

0

虽然这是一个老问题,但我会尝试回答它,因为它仍然没有答案。请注意,我使用您的问题来学习如何使用circlize,所以如果它不是最佳的或有任何错误,我会提前道歉,我将不胜感激。

我必须说我没有按照您建议的方式(连接组)解决,因为它需要按摩输入数据以将其转换为连接组的邻接矩阵。

但是,可以使用您提供的输入数据直接表示您想要观察的大部分信息,这可能会有所帮助。

首先,我创建了一个颜色友好的矢量,默认的颜色有时太暗:

library(RColorBrewer)
qual_col_pals = brewer.pal.info[brewer.pal.info$category == 'qual',]
col_vector = unlist(mapply(brewer.pal, qual_col_pals$maxcolors, rownames(qual_col_pals)))
Nsectors = length(unique(mydf$Group))+length(unique(mydf$Gene)) 
col_vector = col_vector[1:Nsectors]

以其他格式导出透明度存在问题,因此我将创建一个 pdf。我先创建一个没有注释的和弦图,因为基因的标签太多,我稍后会添加它们。我将图表存储在一个名为的变量cdm_res中,这将帮助我稍后检索扇区的位置等。

pdf(file = "circlize_example.pdf",width = 10, height = 10)
# -- Create a chord diagram with no labels nor axis
cdm_res = chordDiagram(x = mydf[,c(2,1,3)],  # I change the order, largest groups on top
              annotationTrack = "grid", # I create it without sector names, it is too crowded
              grid.col = col_vector)

我们将群体和基因联系起来。现在我添加组的标签。

# -- Add now labels, etc.
for(si in unique(mydf$Group)) { # Now I add the labels for Group and the axis
  xlim = get.cell.meta.data("xlim", sector.index = si, track.index = 1)
  ylim = get.cell.meta.data("ylim", sector.index = si, track.index = 1)
  circos.text(mean(xlim), mean(ylim), si, sector.index = si, track.index = 1, 
              facing = "outside", cex=1.2, niceFacing = TRUE)
  circos.axis(h = "top", labels.cex = 0.5, sector.index = si,track.index=1)
}

接下来,我为每个观察创建一个矩形,其高度与 FoldChange 的绝对值成正比,如果为正则为红色,如果为负则为绿色。通过这种方式,您可以看到同一基因何时发生变化。这也可以通过创建另一个轨道来完成。

y1 = ylim[1] + 1.2* (ylim[2] - ylim[1]) # The rectangle will start at the top of the coloured sectors

  for(i in seq_len(nrow(cdm_res))) {
    circos.rect(cdm_res[i, "x1"], y1, cdm_res[i, "x1"] - 
                  abs(cdm_res[i, "value1"]), y1 + abs(cdm_res[i, "value1"]),#(y2-y1)*0.45, 
                col = ifelse(cdm_res[i,"value1"]>0,"red","green"), 
                border = ifelse(cdm_res[i,"value1"]>0,"red","green"),
                sector.index = cdm_res$rn[i], track.index = 1)
  } 

最后,我在最高矩形的末尾添加标签。

for(si in unique(mydf$Gene)) { # For Gene I skip axis and reduce label's size
  xlim = get.cell.meta.data("xlim", sector.index = si, track.index = 1)
  #ylim = get.cell.meta.data("ylim", sector.index = si, track.index = 1)
  idx=which(cdm_res$rn == si) # which are the indxs for this sector?
  height=max(abs(cdm_res$value1[idx])) # we look for the maximum value
  y2_label=4+height # to locate our label at the top of the rect, a little bit further
  circos.text(mean(xlim), mean(ylim), si, sector.index = si, track.index = 1, 
              facing = "outside", 
              cex=0.5, # here the challenge, if the labels are large they will overlap 
              adj=c(degree(0),degree(y2_label)), # increase the offset to make labels larger
              niceFacing = TRUE)
  
}

circos.clear()
dev.off()

结果如下:带circlize的和弦图

于 2020-12-02T21:15:23.453 回答