r - R tsibble 添加对自定义索引的支持
问题描述
问题描述
我经常使用三次月度数据。每月三次(或大约每 10 天一次,也称为十天),这是前苏联水相关数据和世界各地更多气候/水相关数据集的典型报告间隔。以下是具有 2 个变量的示例数据集:
> 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到每年 36 个(类似于一年中的某天)。最优雅的解决方案是为 dekadal 数据使用适当的日期格式,例如yearmonth
. lubridate
但是,lubridate
可能不打算在不久的将来支持 dekadal 数据(github 对话)。
我有使用工作流tsibble
,并且timetk
可以很好地处理月度数据,但是使用原始的十进制时间步骤确实更合适,我正在寻找一种方法,能够以最少的繁琐变通方法将 tidyverse 函数与十进制数据一起使用尽可能。
在 tsibble 中对 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.)。 - 可以向 tsibble 添加自定义索引,但我还没有找到这方面的示例,我不明白我必须如何使用这些功能(小插图仍在计划中)。我已经开始阅读代码以尝试了解如何使用这些函数来获得对 dekadal 数据的支持,但我有点不知所措。
问题
tsibble 中的 dekadal 自定义指数的行为是否与 yearmonth 或 weekyear 类似?
这里有人可以分享如何将自定义索引添加到 tsibble 的示例吗?
或者有人知道在 tidyverse 中优雅地处理 dekadal 数据的另一种方法吗?
解决方案
扩展 tsibble 以支持新索引需要为这些泛型定义方法:
index_valid()
- 如果类可以作为索引,则此方法应返回 TRUEinterval_pull()
- 此方法接受您的索引值并计算数据的间隔。可以使用创建间隔tsibble:::new_interval()
。您可能会发现tsibble::gcd_interval()
计算最小间隔很有用。seq()
-+
这些方法用于使用new_data()
函数生成未来时间值。
'year' 的新 tsibble 索引类的最小示例如下:
library(tsibble)
#>
#> Attaching package: 'tsibble'
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, union
library(vctrs)
# Object creation function
my_year <- function(x = integer()) {
x <- vec_cast(x, integer())
vctrs::new_vctr(x, class = "year")
}
# Declare this class as a valid index
index_valid.year <- function(x) TRUE
# Compute the interval of a year input
interval_pull.year <- function(x) {
tsibble::new_interval(
year = tsibble::gcd_interval(vec_data(x))
)
}
# Specify how sequences are generated from years
seq.year <- function(from, to, by, length.out = NULL, along.with = NULL, ...) {
from <- vec_data(from)
if (!rlang::is_missing(to)) {
vec_assert(to, my_year())
to <- vec_data(to)
}
my_year(NextMethod())
}
# Define `+` operation as needed for `new_data()`
vec_arith.year <- function(op, x, y, ...) {
my_year(vec_arith(op, vec_data(x), vec_data(y), ...))
}
# Use the new index class
x <- tsibble::tsibble(
year = my_year(c(2018, 2020, 2024)),
y = rnorm(3),
index = "year"
)
x
#> # A tsibble: 3 x 2 [2Y]
#> year y
#> <year> <dbl>
#> 1 2018 0.211
#> 2 2020 -0.410
#> 3 2024 0.333
interval(x)
#> <interval[1]>
#> [1] 2Y
new_data(x, 3)
#> # A tsibble: 3 x 1 [2Y]
#> year
#> <year>
#> 1 2026
#> 2 2028
#> 3 2030
由reprex 包于 2021-02-08 创建(v0.3.0)
推荐阅读
- vb.net - 使用结构化数组填充 DataGridView 的问题
- c# - 如何使用 REST api 将文件存储卷挂载到 azure 容器实例
- javascript - 根据 3 个选择器更改表格行
- laravel - 如何在laravel中保存来自视图的数组数据
- python-3.x - ModuleNotFoundError:没有名为“telethon”的模块
- python - 如何解决阶乘过程中的while循环问题>
- python - 我如何对在 Stripe 购买的每件产品收取 0.1(十分之一)美分?
- r - 如何使用 DataExplorer 分割描述性条形图
- dart - 在流构建器列表视图中显示文档快照的引用
- php - 重新启动 PHP 数组索引