保存在列表中时,ggplot2会覆盖绘图

时间:2017-09-06 09:22:48

标签: r ggplot2

我有一个代码来绘制数据帧中的一些数据。 当我在没有循环的情况下运行代码时,它可以工作,但是当我使用代码执行此操作然后执行$ awk -v lines=6 '1; END {for (i=NR; i<lines; ++i) print ""}' file text1 text2 text3 $ awk -v lines=6 '1; END {for (i=NR; i<lines; ++i) print ""}' file | wc -l 6 plots[[1]]时,所有绘图都是相同的但实验室是不同的。

我做错了什么?谢谢

plots[[2]]

1 个答案:

答案 0 :(得分:2)

由于没有提供数据,我将尝试使用R:

中的通用数据集进行演示
data(airquality)
ssgsea.diff <- as.data.frame(airquality)

plots <- list()
combinations <- combn(dim(ssgsea.diff)[2],2)
使用原始代码

重现问题。 for循环完成后有15个地块,&amp;实际上它们都使用不同的标签共享相同的图形:

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
}
下面的

解决方案将导致列表中存储15个不同的图(我还首先定义了列索引,以使代码更具可读性):

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)

解释:由于您为ggplot指定美学映射的方式,所有绘图对象都在循环结束时使用当前(即最后)值i进行评估。更安全的方法是利用ggplot中的data参数,该参数将ggplot对象本身中的数据帧存储为副本而不是引用 。当i在每个循环中发生更改时,ggplot对象中的数据副本不会更改。这两篇文章中的答案进一步讨论了这个问题:Storing ggplot objects in a list from within loop in R&amp; Storing plot objects in a list