意外的将ggplot2参数传递到列表的循环行为

时间:2018-10-02 00:56:02

标签: r ggplot2

因此,我研究了与此相关的其他一些问题: 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)

2 个答案:

答案 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") 

Plot Output