因此,我研究了与此相关的其他一些问题: Storing Plot Objects in a List; Store Plots in List in Loop产生ggplot2对象的列表。
我正在尝试for循环来创建ggplot2参数并将其分配给列表,稍后可以调用该列表以创建图形网格。
Time <- as.POSIXct(origin="1970-01-01",seq(1522461060,1522467000,by=60),tzone="UTC")
P <- abs(rnorm(100,0.0028,sd=0.038))
Qmin <- abs(rnorm(100,0.007,0.0021))
RE.24hr <- sort(rep(1:20,5))
dt1 <- data.table(Time,P,Qmin,RE.24hr)
require(ggplot2)
require(data.table)
REL <- max(dt1$RE.24hr)
hydl <- list()
maxp <- max(dt1$P); maxq <- max(dt1$Qmin,na.rm=T)
i <- 1
我的for循环最后将NULL分配给列表的最后一个条目以外的所有条目:
for(i in REL){
mydata <- subset(dt1,RE.24hr==i)
hydl[[i]] <- ggplot(mydata,aes(x=Time)) + geom_line(aes(y=Qmin),colour='blue') +
geom_line(aes(y=P*10)) + scale_y_continuous(limits=c(0,maxp*10),sec.axis = sec_axis(~./10,name="Precip [m]")) +
theme_bw() + theme(axis.title=element_blank())
plot(hydl[[i]])
}
do.call(grid.arrange, c(hydl, ncol = 5))
但是,当我切换到while循环逻辑时,代码按预期执行:
while(i <= REL){
mydata <- subset(dt1,RE.24hr==i)
hydl[[i]] <- ggplot(mydata,aes(x=Time)) + geom_line(aes(y=Qmin),colour='blue') +
geom_line(aes(y=P*10)) + scale_y_continuous(limits=c(0,maxp*10),sec.axis = sec_axis(~./10,name="Precip [m]")) +
theme_bw() + theme(axis.title=element_blank())
plot(hydl[[i]])
i <- i + 1
}
do.call(grid.arrange, c(hydl, ncol = 5))
我对于为什么将逻辑结构从for循环切换到while循环会改变如何实现对列表的分配感到困惑。我最好的猜测是我忽略了基本的基本编码原理。
R版本3.4.2(2017-09-28) 平台:x86_64-w64-mingw32 / x64(64位) 运行于:Windows 10 x64(内部版本17134)
答案 0 :(得分:2)
不确定为什么要循环播放而不是简单地使用dplyr
并根据需要调整数字la:
df <- data.frame(Time = as.POSIXct(origin="1970-01-01",
seq(1522461060,1522467000, by=60), tzone="UTC"),
P = abs(rnorm(100,0.0028, sd=0.038)),
Qmin = abs(rnorm(100, 0.007, 0.0021)),
RE.24hr = sort(rep(1:20, 5)))
df %>%
ggplot(aes(Time, P)) + geom_line(color = 'blue') +
geom_line(aes(Time, Qmin * 10)) +
facet_wrap(~RE.24hr, scales = 'free_x')
答案 1 :(得分:2)
当前,在您的for
循环中,您不遍历序列,而仅遍历最终值。只需从1到REL
。
for(i in 1:REL){
...
}
尽管如此,考虑使用lapply()
来构建图列表,而无需初始化 hydl ,而无需通过grid.arrange()
将列表直接传递到do.call()
中:
hydl2 <- lapply(1:REL, function(i) {
mydata <- subset(dt1, RE.24hr==i)
ggplot(mydata, aes(x=Time)) +
geom_line(aes(y=Qmin),colour='blue') + geom_line(aes(y=P*10)) +
scale_y_continuous(limits=c(0,maxp*10), sec.axis = sec_axis(~./10,name="Precip [m]")) +
theme_bw() + theme(axis.title=element_blank())
})
grid.arrange(grobs=hydl2, ncol=5)
即使考虑by()
(tapply
的面向对象包装器)并绕过对subset
的需求,因为它通过 RE.24hr < / em>:
hydl3 <- by(dt1, dt1$RE.24hr, function(mydata) {
ggplot(mydata, aes(x=Time)) +
geom_line(aes(y=Qmin),colour='blue') + geom_line(aes(y=P*10)) +
scale_y_continuous(limits=c(0,maxp*10), sec.axis = sec_axis(~./10,name="Precip [m]")) +
theme_bw() + theme(axis.title=element_blank())
})
grid.arrange(grobs=hydl3, ncol=5)
最后,如所述,只需使用facet_wrap
即可处理多个切片图。设计会有所不同。
ggplot(dt1, aes(x=Time)) + geom_line(aes(y=Qmin),colour='blue') +
geom_line(aes(y=P*10)) + scale_y_continuous(limits=c(0,maxp*10),sec.axis = sec_axis(~./10,name="Precip [m]")) +
theme_bw() + theme(axis.title=element_blank()) +
facet_wrap(~RE.24hr, ncol=5, scales="free")