【问题标题】:How to loop through columns and create 2 different graphs using the same data如何遍历列并使用相同的数据创建 2 个不同的图表
【发布时间】:2026-01-01 04:40:01
【问题描述】:

我对 R 有点陌生,并尝试创建一个代码来帮助我循环遍历大型数据集,从而每列生成 2 个图。在这样做时,它必须考虑一些指定的变量并区分它们(参见代码)。 在第一张图中,它应该制作一个箱线图/散点图,我需要在其中区分对照组和患病组。除此之外,我还想看看有事件的人和没有事件的人之间的区别。

这实际上是有效的代码。我现在要添加一个代码,我将该图与变量的直方图结合起来,这样我就可以对数据的分布有一些线索。我试图将其添加到函数中,但不知何故不起作用

此外,我想将这两个图表合并到一个页面中,并在最后循环整个变量集并将其保存为图像(参见代码)

请在下面找到我到目前为止的代码。任何建议都非常感谢

library(ggplot2)
library(purrr)

创建一个包含随机数和 2 个组的数据框

group <- c("Control","PAD","Control","PAD","PAD", "Control","PAD","Control","PAD","PAD", "Control","PAD","Control","PAD","PAD")
b <- round(runif(15, 1, 7)) 
c <- round(runif(15, 1, 3)) 
d <- round(runif(15, 3, 8)) 
e <- round(runif(15, 1, 5))
event <- c("no event", "event" , "no event" , "no event" , "no event", "no event", "event", "no event", "no event" , "no event" , "no event" , "no event", "no event", "event", "event")

加入变量以创建数据框

df <- data.frame(group, b,c,d, e, event)
df

rm(group, b, c, d, e, event)

制作一种新颜色,为标签提供特定颜色(用于 # 用于在 1 个图中对组进行颜色标记)

df$color <- "color"
for (i in 1:dim(df)[1]){
  if (df$group[i]=="Control") {
    df$color[i] <- "Control" # in de column PAD, if the control is control give the color the string "control"
  }
}
for (i in 1:dim(df)[1]){
  if (df$group[i] == "PAD" && df$event[i] == "event") {
    df$color[i] <- "PAD with event" # in de column PAD, if the PAD has event give the color the string "event"
  }
}
for (i in 1:dim(df)[1]){
  if (df$group[i] == "PAD" && df$event[i] == "no event") {
    df$color[i] <- "PAD without event"
  }
}
rm(i)

按索引拉出名字 创建 1 个解释变量 用作解释值(第 1 列)

expl = names(df[1]) 

用于循环遍历列 2:5

response = names(df[2:5]) 

使用命名向量

response = set_names(response)
response

expl = set_names(expl)
expl

散点图 功能的第一部分有效 函数的第 1 部分

scatter_fun = function(x, y) {
  ggplot(df, aes(x = .data[[x]], y = .data[[y]], color=color) ) + 
    geom_boxplot(fill="lightgrey", colour= "black", alpha=0.7,  
                 outlier.shape=NA) + 



geom_point(position = position_jitter(0.2)) +
    scale_color_manual(values= c("Control"="Orange", "PAD with event" = "Red", "PAD without event"="Green")) + # color the values as as you please
    labs(x = "",
         y = y,
         caption = "") +
    theme_bw() +
    theme(panel.grid.major = element_line(size = 0.1, linetype = 'solid',
                                          colour = "grey"), 
          panel.grid.minor = element_line(size = 0.05, linetype = 'solid',
                                          colour = "grey"),

          legend.title = element_blank(),
          legend.text = element_text(size=13),
          legend.key.size = unit(3,"line"))

函数的第 2 部分(不起作用) 向函数添加直方图 这是对我来说变得复杂的部分。我想从函数中得到 3 件事 1 上半部分给了我一个箱线图和一个散点图 2 下面的部分我想要循环列的直方图(在本例中为 b) 感受一下价值的分布 3 最后使用该功能我想将一页上的两列传输两个PDF 循环遍历列时的文件 要了解这个情节发生了什么,可以删除,可以使用下面的示例 举个例子 向函数添加直方图

ggplot(df, aes(x =.data[[x]])) +
    geom_histogram(fill="Orange", color="black", stat = "count")

}

仅指定列名时的工作原理示例

loopplots = map(expl, ~scatter_fun(.x, "b") ) 
loopplots

当我运行它时,它将控制和 PAD 分开,但是我不希望它们分开,而只是想要对两个组的分布有一个总体了解

整个循环:当我运行这部分时,它只保存函数的后半部分

event_vs_no_event = map(response,
                        ~map(expl, scatter_fun, y = .x) )

检查 b 上保存的内容

event_vs_no_event$b

将所有图像保存到 1 个 PDF --> 在这里我希望将对应于 1 列的直方图和散点图保存到 1 页中。

pdf("event_vs_no_event.pdf")
event_vs_no_event
dev.off() 

【问题讨论】:

    标签: r loops ggplot2


    【解决方案1】:

    我建议使用某物。像这样作为一个起点。在 ggplot 中使用长数据帧比使用宽数据帧更方便。在这里,我使用 tidyr 的 gather 来制作长数据帧。

    library(tidyverse)
    p1 <- df %>% 
      gather(response , value, -group, -event) %>% 
      ggplot(aes(group, value, color = event)) + 
       geom_boxplot(show.legend = F) + 
       geom_point(position = position_dodge(width = 0.8), show.legend = F) +  
       facet_wrap(~response, scales = "free_y")
    
    p2 <- df %>% 
      gather(response , value, -group, -event) %>% 
      ggplot(aes(value)) + 
      geom_histogram(fill="Orange", color="black", bins= 6) + 
      facet_wrap(~response, scales = "free") 
    
    library(cowplot)
    
    plot_grid(p1, p2, ncol = 1)
    

    编辑

    没有循环的最整洁的方法是 s.th。像这样。

    library(ggbeeswarm)
    library(cowplot)
    library(tidyverse)
    plots <- df %>% 
      gather(response , value, -group, -event) %>% 
      nest(-response) %>% 
      mutate(box_scatter = map2(data, response, ~ggplot(.x,aes(group, value)) + 
            geom_boxplot(show.legend = F) + 
            geom_beeswarm(aes(color = event)) +
            ggtitle(.y))) %>% 
      mutate(hist = map(data, ~ ggplot(.,aes(value)) + 
                          geom_histogram(fill="Orange", color="black", bins= 6)+
                          ggtitle("")))
    
    pdf("all_plots.pdf", width = 15)
    map2(plots$box_scatter, plots$hist, 
        ~plot_grid(.x, .y, ncol = 2, labels ="auto"))
    dev.off()
    

    当然你也可以使用for循环

    pdf("all_plots.pdf", width = 15)
    for (i in names(df)[2:5]){
      p1 <- ggplot(df, aes_string("group",i)) + 
        geom_boxplot(show.legend = F) + 
        geom_beeswarm(aes(color = event))
    
      p2 <- ggplot(df,aes_string(i)) + 
        geom_histogram(fill="Orange", color="black", bins= 6)
    
      p_all <- plot_grid(p1, p2)
      print(p_all)
    } 
    dev.off()
    

    【讨论】:

    • 虽然有一个问题,但也许是我缺乏使用 R 编码的经验我有 290 个变量,我想在附件中可视化:1 个散点图/箱线图和 1 页上的相应直方图。然后循环到下一列并重现相同但使用下一个变量。最后,我希望打印:每页 1 个变量(两个图)。我添加了一个附件,以便您查看它的外观。
    最近更新 更多