首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >添加对自定义索引的支持

添加对自定义索引的支持
EN

Stack Overflow用户
提问于 2021-01-22 13:32:13
回答 1查看 459关注 0票数 0

问题描述

我经常使用trice月度数据。Trice月报(或大约每10天一次,也称为dekad)是前苏联与水有关的数据和世界各地更多与气候/水有关的数据的典型报告间隔。下面是一个包含两个变量的示例数据集:

代码语言:javascript
复制
> 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会话)。

我有使用tsibbletimetk的工作流,它们可以很好地处理每月数据,但是使用原始的dekadal时间步骤确实更合适,我正在寻找一种方法,可以使用dekadal数据来使用tidyverse函数,并且尽可能少使用繁琐的变通方法。

对于tsi球中的dekadal数据使用每日日期存在的问题是,将时间间隔确定为每天,每个月的3个值之间存在大量的数据缺口:

代码语言:javascript
复制
> 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
# … 

我到目前为止所做的事情如下:

  1. 我认为这里有可能在tsibble中将有序因素定义为指数,但timetk不承认因素为指数。timetk建议定义自定义索引(参见2.)。
  2. 将自定义索引添加到tsi球中是有可能的,但是我还没有找到这方面的例子,我也不明白如何使用这些函数(目前仍在计划中)。我已经开始阅读代码,试图了解如何使用这些函数来获得dekadal数据的支持,但我有点不知所措。

问题

  • tsibble中的dekadal自定义指数会与年度月份或工作日相似吗?
  • 这里的任何人会有一个例子来分享如何添加自定义索引到tsi球吗?
  • 或者有人知道另一种方法来优雅地处理潮间带中的数据?
EN

回答 1

Stack Overflow用户

发布于 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执行逆变换。它实际上不是在下面使用,但可能有用。

代码语言:javascript
复制
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对象:

代码语言:javascript
复制
        A  B
2019(1) 1 10
2019(2) 2 20
2019(3) 3 30
2019(4) 4 40
2019(5) 5 50

备注

代码语言:javascript
复制
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))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65846176

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档