我有一个代码来绘制数据帧中的一些数据。
当我在没有循环的情况下运行代码时,它可以工作,但是当我使用代码执行此操作然后执行$ 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]]
答案 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