针对长数据帧的所有组的散点图

时间:2019-04-09 11:39:26

标签: r ggplot2 dplyr tidyr

我很确定已经问过类似的问题,但是我不知道如何搜索。

我经常以3种实验(a-c)的小示例的形式获得广泛格式的数据。我通常会转换为长格式,并通过某些函数(以log2为例)转换值。

我通常想做的是相互绘制所有实验,在这里我正在寻找一种方便的解决方案。如何使用a~ba~cb~c ...转换我的数据框以获取构面...

到目前为止,我再次tidy::spread进行数据处理,并执行了ggplot命令3次,每个命令的列名分别为xy。后来我将各个图合并在一起。

有更方便的方法吗?

library(dplyr)
library(tidyr)
library(ggplot2)

df <- data.frame(
  names=letters,
  a=1:26,
  b=1:13,
  c=11:36
)

df %>%
  tidyr::gather(experiment, value, -names) %>%
  mutate(log2.value=log2(value)) 

编辑
由于我从@hdkrgr得到了一个非常有用的答案,因此我修改了一些代码。 inner_join是一个很棒的技巧,我可以实现它以使我的想法自动化,但我仍然想念一个聪明的过滤器来去除多余的数据,因为我不想绘制c~c或{ {1}}(如果我已经绘制了b~a)。 我现在通过提供我想要的配对解决了这个问题,但是谁能想到ob一个简单的解决方案?我想不出能给我带来独特配对的东西。

a~b

4 个答案:

答案 0 :(得分:4)

从长格式开始的一种方法是对长数据进行自连接,以获取每行中两个实验的所有组合:

df %>%
    tidyr::gather(experiment, value, -names) %>%
    mutate(log2.value=log2(value)) %>%
    inner_join(., ., by=c("names")) %>% 
    ggplot(aes(log2.value.x, log2.value.y)) + geom_point() + facet_grid(experiment.y ~ experiment.x)

enter image description here

编辑:为避免绘制多余的实验对,您可以执行以下操作:

df %>%
    tidyr::gather(experiment, value, -names) %>%
    mutate(log2.value=log2(value)) %>% inner_join(., ., by=c("names")) %>% 
    filter(experiment.x < experiment.y) %>% 
    ggplot(aes(log2.value.x, log2.value.y)) + geom_point() + facet_wrap(~experiment.y + experiment.x)

enter image description here

答案 1 :(得分:3)

这真的很有趣,因为它实际上比最初看起来要复杂。突出的一件事是获得唯一对实验-似乎您想要a vs b,但不一定也想要b vs a。为此,您需要一组独特的实验对。

最初,我尝试使用您的gather数据,但是意识到从宽版本开始可能更简单。从列名中获取实验的名称(可以采用多种方法,但我只是采用了非"names"的字符串)并获得它们的组合。我将它们粘贴在一起,使它们更易于使用。

library(dplyr)
library(tidyr)
library(ggplot2)

df <- data.frame(
  names=letters,
  a=1:26,
  b=1:13,
  c=11:36
) %>%
  as_tibble()

exp <- stringr::str_subset(names(df), "names", negate = T)

pairs <- combn(exp, 2, paste, simplify = F, collapse = ",") %>%
  unlist()
pairs
#> [1] "a,b" "a,c" "b,c"

然后,对于每一对,提取关联的列名称,进行一些tidyeval选择这些列,然后进行log2转换。我不得不绕道而行,以使用可以参考的名称来重命名列-我认为这是没有必要的,但是我无法在ggplot aes中使用我的tidyeval。可能有人对此有想法。然后进行绘图,并相应地标记轴和标题。剩下的就是三个地块的列表。

plots <- purrr::map(pairs, function(pair) {
  cols <- strsplit(pair, split = ",", fixed = T)[[1]]
  df %>%
    select(names, !!cols[1], !!cols[2]) %>%
    mutate_at(vars(-names), log2) %>%
    rename(exp1 = !!cols[1], exp2 = !!cols[2]) %>%
    ggplot(aes(x = exp1, y = exp2)) +
      geom_point() +
      labs(x = cols[1], y = cols[2], title = pair)
})

根据需要使用选择的方法将图放在一起。我选择了cowplot,但我也喜欢patchwork软件包。

cowplot::plot_grid(plotlist = plots, nrow = 1)

答案 2 :(得分:2)

这可能不是您想要的,但是如果目的是探索每个变量之间的相关模式,则可能需要考虑ggpairs包中的GGally。它不仅提供散点图,而且提供相关性得分和分布。

library(GGally)

ggpairs(df[, c("a", "b", "c")])

enter image description here

答案 3 :(得分:1)

您可以先通过combn创建所有组合,然后逐步完成:

library(purrr)

t(combn(names(df)[-1], 2)) %>% ## get all combinations  
   as.data.frame(stringsAsFactors = FALSE) %>% 
   mutate(l = paste(V1, V2, sep = " vs. ")) %>%
   pmap_dfr(function(V1, V2, l) 
     df %>% 
       select(one_of(c(V1, V2))) %>% ## select the elements given by the combination
       mutate_all(log2) %>%
       setNames(c("x", "y")) %>%
       mutate(experiment = l)) %>%
   ggplot(aes(x, y)) + geom_point() + facet_wrap(~experiment)

Scatterplot