问题描述
我经常使用trice月度数据。Trice月报(或大约每10天一次,也称为dekad)是前苏联与水有关的数据和世界各地更多与气候/水有关的数据的典型报告间隔。下面是一个包含两个变量的示例数据集:
> date = unique(floor_date(seq.Date(as.Date("2019-01-01"), as.Date("2019-12-31"),
by="day"), "10days"))
> example_data <- tibble(
date = date[day(date)!=31],
value = seq(1,36,1),
var = "A") %>%
add_row(tibble(
date = date[day(date)!=31],
value = seq(10,360,10),
var = "B"))
> example_data
# A tibble: 72 x 3
# Groups: var [2]
date value var
<ord> <dbl> <chr>
1 2019-01-01 1 A
2 2019-01-01 10 B
3 2019-01-11 2 A
4 2019-01-11 20 B
5 2019-01-21 3 A
6 2019-01-21 30 B
7 2019-02-01 4 A
8 2019-02-01 40 B
9 2019-02-11 5 A
10 2019-02-11 50 B
# … with 62 more rows在示例中,我选择了1.、11.和21。到目前为止,这几十年,但实际上更合适的索引是每月1至3(类似于每年1至12个月)或在德卡德每年1至36 (模拟到日)。最优雅的解决方案是为dekadal数据(如yearmonth in lubridate )提供适当的日期格式。然而,lubridate可能不会计划在不久的将来支持dekadal数据(github会话)。
我有使用tsibble和timetk的工作流,它们可以很好地处理每月数据,但是使用原始的dekadal时间步骤确实更合适,我正在寻找一种方法,可以使用dekadal数据来使用tidyverse函数,并且尽可能少使用繁琐的变通方法。
对于tsi球中的dekadal数据使用每日日期存在的问题是,将时间间隔确定为每天,每个月的3个值之间存在大量的数据缺口:
> example_data_tsbl <- as_tsibble(example_data, index = date, key = var)
> count_gaps(example_data_tsbl, .full = FALSE)
# A tibble: 70 x 4
var .from .to .n
<chr> <date> <date> <int>
1 A 2019-01-02 2019-01-10 9
2 A 2019-01-12 2019-01-20 9
3 A 2019-01-22 2019-01-31 10
# … 我到目前为止所做的事情如下:
tsibble中将有序因素定义为指数,但timetk不承认因素为指数。timetk建议定义自定义索引(参见2.)。问题
发布于 2021-01-22 17:49:02
这并没有讨论tsibbles,但是它太长了,不能发表评论,并且提供了一个替代方案。
动物园可以通过(1)以下不需要创建新类的代码或(2)创建一个新的类和方法来做到这一点。对于这种选择,遵循yearmon类所拥有的方法就足够了。见这里。动物园本身不需要修改。
如下文所示,第一种方法的日期将显示为周期为1、2、.和36的年份(周期)。在内部,日期存储为年份+(循环-1)/36。
如果日期是连续的三个月(或者如果您不介意插入NAs使其成为这样的日期,也可以使用ts类)。为此,请使用as.ts(z)。
在没有加载包的情况下启动一个新的会话,然后复制并粘贴注释中所示的输入DF,然后是下面的代码。Date2dek将将表示标准yyyy格式的日期的日期矢量或字符向量转换为上面描述的dek格式。dek2Date执行逆变换。它实际上不是在下面使用,但可能有用。
library(zoo)
# convert Date or yyyy-mm-dd char vector
Date2dek <- function(x, ...) with(as.POSIXlt(x, tz="GMT"),
1900 + year + (mon + ((mday >= 11) + (mday >= 21)) / 3) / 12)
dek2Date <- function(x, ...) { # not used below but shows inverse
cyc <- round(36 * (as.numeric(x) %% 1)) + 1
if(all(is.na(x))) return(as.Date(x))
month <- (cyc - 1) %/% 3 + 1
day <- 10 * ((cyc - 1) %% 3) + 1
year <- floor(x + .001)
ix <- !is.na(year)
as.Date(paste(year[ix], month[ix], day[ix], sep = "-"))
}
# DF given in Note below
z <- read.zoo(DF, split = "var", FUN = Date2dek, regular = TRUE, freq = 36)
z结果是以下zooreg对象:
A B
2019(1) 1 10
2019(2) 2 20
2019(3) 3 30
2019(4) 4 40
2019(5) 5 50备注
DF <- data.frame(
date = as.Date(ISOdate(2019, rep(1:2, 3:2), c(1, 11, 21))),
value = c(1:5, 10*(1:5)),
var = rep(c("A", "B"), each = 5))https://stackoverflow.com/questions/65846176
复制相似问题