我想在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中的循环。所以......任何人?
答案 0 :(得分:1)
我们使用melt
从长到长重新整形数据,因此我们可以将V1
,V2
和V3
作为单个列进行操作。然后我们创建月份组。我使用dplyr
链接运算符(%>%
)完成了所有这些操作。
现在我们有了所需格式的数据,我们使用lapply
为每个月的每个原始值列创建时间序列图。 split
函数将数据框拆分为每个月的单独数据框,以便我们可以为每个月的数据创建单独的图。 lapply
和split
的这种组合避免了显式循环。
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"]]
您可以将这些图表保存到单个文件中,也可以将它们放在一个页面上并保存。或者,如果您另存为PDF,则可以在每页上创建一个包含单个图表的多页PDF。
如果您想在不同的图表中使用V1
,V2
和V3
,您可以执行类似于上述代码的操作,但稍微更改split
要按month
和variable
进行拆分的功能:
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"]]