for loop with ggplots生成具有相同值但标题不同的图形

for loop with ggplots生成具有相同值但标题不同的图形,r,for-loop,ggplot2,cowplot,R,For Loop,Ggplot2,Cowplot,我读过很多关于使用循环来生成大量图形的帖子,但是找不到任何可以解释我的问题的帖子 我有一个数据框,正在尝试循环92列,为每列创建一个新的图表。我想将每个绘图保存为单独的对象。当我运行我的循环(下面的代码)并打印图表时,所有的图表都是正确的。但是,当我使用assign()更改print()命令时,图形不正确。标题正在发生变化,但图形值都是相同的(它们都是最终图形的值)。我发现了这一点,因为当我使用plot_grid()生成一个包含10个图的图形时,图形标题和轴标签都是正确的,但值是相同的 我的数据

我读过很多关于使用循环来生成大量图形的帖子,但是找不到任何可以解释我的问题的帖子

我有一个数据框,正在尝试循环92列,为每列创建一个新的图表。我想将每个绘图保存为单独的对象。当我运行我的循环(下面的代码)并打印图表时,所有的图表都是正确的。但是,当我使用assign()更改print()命令时,图形不正确。标题正在发生变化,但图形值都是相同的(它们都是最终图形的值)。我发现了这一点,因为当我使用plot_grid()生成一个包含10个图的图形时,图形标题和轴标签都是正确的,但值是相同的

我的数据集很大,所以我提供了一个小的数据集用于下面的说明

示例数据:

library(ggplot)
library(cowplot)
df <- as.data.frame(cbind(group=c(rep("A", 4), rep("B", 4)), a=sample(1:100, 8), b=sample(100:200, 8), c=sample(300:400, 8))) #make data frame
cols <- 2:4 #define columns for plots
for(i in 1:length(cols)){
  df[,cols[i]] <- as.numeric(as.character(df[,cols[i]]))
} #convert columns to numeric
库(ggplot)
图书馆(cowplot)

df我已经清理了您如何生成示例数据帧

library(ggplot2)
library(cowplot)

df <- data.frame(group=c(rep("A", 4), rep("B", 4)),
                          a=sample(1:100, 8),
                          b=sample(100:200, 8),
                          c=sample(300:400, 8)) #make data frame
库(ggplot2)
图书馆(cowplot)

df处理此问题有两种标准方法:

1-使用长格式data.frame

2-使用
aes_string
引用宽格式data.frame中的变量名

这是一个可能策略的例子

library(ggplot2)
library(gridExtra)

# data from other answer
df <- data.frame(group=c(rep("A", 4), rep("B", 4)),
                 a=sample(1:100, 8),
                 b=sample(100:200, 8),
                 c=sample(300:400, 8))

## first method: long format
m <- reshape2::melt(df, id = "group")
p <- ggplot(m, aes(x=group, y=value)) +
    geom_boxplot() 

pl <- plyr::dlply(m, "variable", function(.d) p %+% .d + ggtitle(unique(.d$variable)))
grid.arrange(grobs=pl)

## second method: keep wide format
one_plot <- function(col = "a")  ggplot(df, aes_string(x="group", y=col)) +  geom_boxplot() + ggtitle(col)
pl <- plyr::llply(colnames(df)[-1], one_plot)
grid.arrange(grobs=pl)

## third method: more explicit looping

pl <- vector("list", length = ncol(df)-1)
for(ii in seq_along(pl)){
  .col <- colnames(df)[-1][ii]
  .p <- ggplot(df, aes_string(x="group", y=.col)) +  geom_boxplot() + ggtitle(.col)
  pl[[ii]] <- .p
}

grid.arrange(grobs=pl)
库(ggplot2)
图书馆(gridExtra)
#其他答案的数据

非常感谢您的详细回答。我必须思考一下local在做什么,并重新定义“I”。
aes()
应该指变量名,而不是像
df[,I]
这样的数字向量。这样做可能会导致意外的结果,例如在没有注意到的情况下绘制错误的数据。更不用说使用

library(ggplot2)
library(cowplot)

df <- data.frame(group=c(rep("A", 4), rep("B", 4)),
                          a=sample(1:100, 8),
                          b=sample(100:200, 8),
                          c=sample(300:400, 8)) #make data frame


for (i in 2:ncol(df)){

  g <- ggplot(df, aes(x=group, y=df[,i])) +
    geom_boxplot() +
    ggtitle(colnames(df)[i])

  print(g)
  assign(colnames(df)[i], g) #generate an object for each plot
}   
for (i in 2:ncol(df))  
     local({
  i <- i
  g <<- ggplot(df, aes(x=group, y=df[,i])) +
    geom_boxplot() +
    ggtitle(colnames(df)[i])
  print(i)
  print(g)
  assign(colnames(df)[i], g, pos =1) #generate an object for each plot
     })

plot_grid(a, b, c)
library(ggplot2)
library(gridExtra)

# data from other answer
df <- data.frame(group=c(rep("A", 4), rep("B", 4)),
                 a=sample(1:100, 8),
                 b=sample(100:200, 8),
                 c=sample(300:400, 8))

## first method: long format
m <- reshape2::melt(df, id = "group")
p <- ggplot(m, aes(x=group, y=value)) +
    geom_boxplot() 

pl <- plyr::dlply(m, "variable", function(.d) p %+% .d + ggtitle(unique(.d$variable)))
grid.arrange(grobs=pl)

## second method: keep wide format
one_plot <- function(col = "a")  ggplot(df, aes_string(x="group", y=col)) +  geom_boxplot() + ggtitle(col)
pl <- plyr::llply(colnames(df)[-1], one_plot)
grid.arrange(grobs=pl)

## third method: more explicit looping

pl <- vector("list", length = ncol(df)-1)
for(ii in seq_along(pl)){
  .col <- colnames(df)[-1][ii]
  .p <- ggplot(df, aes_string(x="group", y=.col)) +  geom_boxplot() + ggtitle(.col)
  pl[[ii]] <- .p
}

grid.arrange(grobs=pl)