当保存在列表中时,ggplot2将覆盖图 [英] ggplot2 overwrites plots when saving in a list
问题描述
我有一个代码来绘制数据框中的一些数据。
当我运行没有循环的代码时,它能正常工作,但是当我使用代码执行代码时,然后执行 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屋!