绘制10分钟数据中的月度数据

时间:2016-10-26 15:39:33

标签: r loops date ggplot2 dplyr

我想在10分钟的时间序列中生成月度图。时间序列的开头和结尾对于每个数据集都是不同的,因此它应该通常有效。此外,还应为不同的变量生成图表。

我有一个非常丑陋的解决方案,多年来一个循环和几个月的另一个,这有效,但也产生一些空的额外情节。我希望代码能让它更容易理解。

@media (max-width: 767px){
  .btn-block-xs {
    display: block;
    width: 100%;
    margin-bottom: 10px;
  }
}

所以,必须有更好的方法。我现在正在努力解决这个问题(相同的测试数据):

library(dplyr)
library(readr)
library(tidyverse)
library(ggplot2)
library(lubridate)

#test data:

TDF <- tibble(DATE = seq( make_datetime(2007,09,23,06,00), make_datetime(2008,07,05,23,00), by = 600),
              V1 = round(runif(length(DATE)),2),
              V2 = round(runif(length(DATE)),2),
              V3 = round(runif(length(DATE)),2)
)


for (year in min( year( TDF$DATE)) : max( year( TDF$DATE))) {
  for (mon in min( month( TDF$DATE)) : max( month( TDF$DATE))) {
    for (var in c( "V1", "V2", "V3")) {
      filename <- paste0("Abb/", var, "_", year, "-", mon, "_ZR.png")
      png(filename, width = 1800, height = 900, res = 200)
      p <- ggplot( TDF[ year(TDF$DATE) == year & month(TDF$DATE) == mon,])
      p <- p + geom_line( aes_string( "DATE", paste0(var)))
      print(p)
      graphics.off()
    }
  }
}

这真让我感到困惑,因为

yearmonmin <- TDF$DATE %>% min() %>% floor_date(unit = "month") 
yearmonmax <- TDF$DATE %>% max() %>% ceiling_date(unit = "month")

seq(yearmonmin, yearmonmax, by = "month")

for (yearmon in seq(yearmonmin, yearmonmax, by = "month")) {
  print(var)
}

BUT

> seq(yearmonmin, yearmonmax, by = "month")
 [1] "2007-09-01 UTC" "2007-10-01 UTC" "2007-11-01 UTC" "2007-12-01 UTC" "2008-01-01 UTC" "2008-02-01 UTC" "2008-03-01 UTC" "2008-04-01 UTC"
 [9] "2008-05-01 UTC" "2008-06-01 UTC" "2008-07-01 UTC" "2008-08-01 UTC"    

我已经尝试> for (yearmon in seq(yearmonmin, yearmonmax, by = "month")) { + print(yearmon) + } [1] 1188604800 [1] 1191196800 [1] 1193875200 [1] 1196467200 [1] 1199145600 [1] 1201824000 [1] 1204329600 [1] 1207008000 [1] 1209600000 [1] 1212278400 [1] 1214870400 [1] 1217548800 了两天其他不值得在这里展示的替代方案......

我听说最好避免R中的循环。所以......任何人?

1 个答案:

答案 0 :(得分:1)

我们使用melt从长到长重新整形数据,因此我们可以将V1V2V3作为单个列进行操作。然后我们创建月份组。我使用dplyr链接运算符(%>%)完成了所有这些操作。

现在我们有了所需格式的数据,我们使用lapply为每个月的每个原始值列创建时间序列图。 split函数将数据框拆分为每个月的单独数据框,以便我们可以为每个月的数据创建单独的图。 lapplysplit的这种组合避免了显式循环。

library(lubridate)
library(ggplot2)
library(reshape2)
library(dplyr)

# Reshape to long and add month grouping
TDF = TDF %>% melt(id.var="DATE") %>%
  arrange(DATE) %>%
  mutate(month = paste0(month(DATE, label=TRUE, abbr=TRUE)," ", year(DATE)),
         month = factor(month, levels=unique(month)))

# Create a list of plots by month
pl = lapply(split(TDF, TDF$month), function(df) {
  ggplot(df, aes(DATE, value)) +
    geom_line(aes(group=variable)) +
    facet_grid(. ~ variable) +
  theme(axis.text.x = element_text(angle=-90, hjust=0, vjust=0.5))
})

您现在有一个列表,其中每个列表元素包含一个月数据的图表。例如:

pl[["Sep 2007"]] 

enter image description here

您可以将这些图表保存到单个文件中,也可以将它们放在一个页面上并保存。或者,如果您另存为PDF,则可以在每页上创建一个包含单个图表的多页PDF。

如果您想在不同的图表中使用V1V2V3,您可以执行类似于上述代码的操作,但稍微更改split要按monthvariable进行拆分的功能:

pl = lapply(split(TDF, paste(TDF$variable, TDF$month)), function(df) {
  ggplot(df, aes(DATE, value)) +
    geom_line(aes(group=variable)) +
    facet_grid(. ~ variable) +
    theme(axis.text.x = element_text(angle=-90, hjust=0, vjust=0.5))
})

现在,列表中的每个元素都是每个月每个变量的单个图:

pl[["V1 Apr 2008"]]

enter image description here