当保存在列表中时,ggplot2将覆盖图 [英] ggplot2 overwrites plots when saving in a list

查看:160
本文介绍了当保存在列表中时,ggplot2将覆盖图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代码来绘制数据框中的一些数据。
当我运行没有循环的代码时,它能正常工作,但是当我使用代码执行代码时,然后执行 plots [[1]] 图[[2]] 所有图都是相同的,但实验室是不同的。



我做错了什么?谢谢

 # - 地块
地块< - list()
组合< - combn( dim(ssgsea.diff)[2],2)

for(i in 1:dim(combinations)[2]){

fit < - lm(ssgsea .diff [,组合[1,i]]〜ssgsea.diff [,组合[2,i]],
data = ssgsea.diff)

plot1< - ggplot(ssgsea .diff)+
aes(ssgsea.diff [,组合[1,i]],ssgsea.diff [,组合[2,i]])+
geom_point()

plot1< - plot1 +
labs(x = names(ssgsea.diff)[combinations [1,i]],
y = names(ssgsea.diff)[combinations [2,i]] )+
geom_smooth(method =lm,col =red)+
labs(title = paste(Adj R2 =,signif(summary(fit)$ adj.r.squared, 5),
Slope =,signif(fit $ coef [[2]],5),
Pval =,signif(汇总(拟合)$ coef [2,4],5 )))

plots [[i]]< - plot1
}


解决方案

由于没有数据i我将尝试使用R的一个通用数据集来演示:

  data(airquality)
ssgsea。 diff < - as.data.frame(airquality)

plots< - list()
combinations < - combn(dim(ssgsea.diff)[2],2)

使用原始代码重现问题。 for循环完成后有15个图,&事实上,它们全都与不同的标签共享同一个图表:



pre $ for(i in 1:dim(combinations)[2]){
$ b $ fit< - lm(ssgsea.diff [,组合[1,i]]〜ssgsea.diff [,组合[2,i]],
data = ssgsea.diff)

plot1< - ggplot(ssgsea.diff)+
aes(ssgsea.diff [,combination [1,i]],ssgsea.diff [,combinations [2,i]] )+
geom_point()

plot1< - plot1 +
labs(x = names(ssgsea.diff)[combinations [1,i]],
y = name(ssgsea.diff)[combinations [2,i]])+
geom_smooth(method =lm,col =red)+
labs(title = paste(Adj R2 = signif(摘要(fit)$ adj.r.squared,5),
Slope =,signif(fit $ coef [[2]],5),
Pval =, signif(summary(fit)$ coef [2,4],5)))

plot [[i]] < - plot1
}

解决方案下方会导致列表中存储15个不同的地块(我也是de首先对列索引进行罚款,以使代码更易读):

  for(i in 1:dim(combinations)[2 ]){

#define列索引&列名首先
C1 < - 组合[1,i]; C1.name< - names(ssgsea.diff)[C1]
C2< - 组合[2,i]; C2.name< - names(ssgsea.diff)[C2]

fit< - lm(ssgsea.diff [,C1]〜ssgsea.diff [,C2])#无需指定这里的数据

plot1< - ggplot(ssgsea.diff)+
aes_string(C1.name,C2.name)+ geom_point()

plot1< - plot1 +
labs(x = C1.name,y = C2.name)+
geom_smooth(method =lm,col =red)+
labs(title = paste (Adj R2 =,signif(summary(fit)$ adj.r.squared,5),
Slope =,signif(fit $ coef [[2]],5),
Pval =,signif(摘要(适合)$ coef [2,4],5)))

地块[[i]] < - plot1
}

rm(C1,C2,C1.name,C2.name,fit,plot1,i)



解释:由于您为ggplot指定审美映射的方式,所有绘图对象都在循环结束时用当前(即最后一个)值。更安全的方法是利用ggplot中的 data 参数,该参数将数据框存储在ggplot对象本身中而不是 copy ,而不是一个参考。当 i 在每个循环中发生更改时,ggplot对象中的数据副本不会更改。这两篇文章的答案将进一步讨论:存储列表中的ggplot对象来自R中的循环& 将图表对象存储在列表中


I've a code to plot some data from a dataframe. When I run the code without the loop it works, but when I do it using the code and then do plots[[1]] plots[[2]] all plots are the same but the labs are different.

What I'm doing wrong? Thanks

#-- Plots
plots <- list()
combinations <- combn(dim(ssgsea.diff)[2],2)

for (i in 1:dim(combinations)[2]){

  fit <- lm(ssgsea.diff[,combinations[1,i]] ~ ssgsea.diff[,combinations[2,i]], 
            data = ssgsea.diff)

  plot1 <- ggplot(ssgsea.diff) + 
    aes(ssgsea.diff[,combinations[1,i]], ssgsea.diff[,combinations[2,i]]) + 
    geom_point()

  plot1 <- plot1 + 
    labs(x = names(ssgsea.diff)[combinations[1,i]], 
         y = names(ssgsea.diff)[combinations[2,i]]) + 
    geom_smooth(method="lm", col = "red") + 
    labs(title = paste("Adj R2 = ", signif(summary(fit)$adj.r.squared, 5), 
                       " Slope =",signif(fit$coef[[2]], 5), 
                       " Pval =",signif(summary(fit)$coef[2,4], 5)))

  plots[[i]] <- plot1
}

解决方案

Since no data is provided, I'll attempt to demonstrate with a common dataset from R:

data(airquality)
ssgsea.diff <- as.data.frame(airquality)

plots <- list()
combinations <- combn(dim(ssgsea.diff)[2],2)

Reproduce the problem using the original code. There are 15 plots after the for loop's completion, & indeed they all share the same graph with different labels:

for (i in 1:dim(combinations)[2]){

  fit <- lm(ssgsea.diff[,combinations[1,i]] ~ ssgsea.diff[,combinations[2,i]], 
            data = ssgsea.diff)

  plot1 <- ggplot(ssgsea.diff) + 
    aes(ssgsea.diff[,combinations[1,i]], ssgsea.diff[,combinations[2,i]]) + 
    geom_point()

  plot1 <- plot1 + 
    labs(x = names(ssgsea.diff)[combinations[1,i]], 
         y = names(ssgsea.diff)[combinations[2,i]]) + 
    geom_smooth(method="lm", col = "red") + 
    labs(title = paste("Adj R2 = ", signif(summary(fit)$adj.r.squared, 5), 
                       " Slope =",signif(fit$coef[[2]], 5), 
                       " Pval =",signif(summary(fit)$coef[2,4], 5)))

  plots[[i]] <- plot1
}

Solution below will result in 15 different plots stored in the list (I also defined the column indices first, to make the code more readable):

for (i in 1:dim(combinations)[2]){

  # define column indices & column names first
  C1 <- combinations[1, i]; C1.name <- names(ssgsea.diff)[C1]
  C2 <- combinations[2, i]; C2.name <- names(ssgsea.diff)[C2]

  fit <- lm(ssgsea.diff[, C1] ~ ssgsea.diff[, C2]) # no need to specify data here

  plot1 <- ggplot(ssgsea.diff) + 
    aes_string(C1.name, C2.name) + geom_point()

  plot1 <- plot1 + 
    labs(x = C1.name, y = C2.name) + 
    geom_smooth(method="lm", col = "red") + 
    labs(title = paste("Adj R2 = ", signif(summary(fit)$adj.r.squared, 5), 
                       " Slope =", signif(fit$coef[[2]], 5), 
                       " Pval =", signif(summary(fit)$coef[2, 4], 5)))

  plots[[i]] <- plot1
}

rm(C1, C2, C1.name, C2.name, fit, plot1, i)

Explanation: Due to the way you specified the aesthetic mapping for ggplot, all the plot objects were evaluated at the end of the loop with the current (i.e. last) value of i. A safer method would be to take advantage of the data argument in ggplot, which stores the data frame in the ggplot object itself as a copy rather than a reference. When i changes through each loop, the data copy in the ggplot object does not change. Answers in these two posts discuss this further: Storing ggplot objects in a list from within loop in R & Storing plot objects in a list.

这篇关于当保存在列表中时,ggplot2将覆盖图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆