【问题标题】:How can I create dates in Year/Semester format in R?如何在 R 中创建年/学期格式的日期?
【发布时间】:2018-06-08 14:50:42
【问题描述】:

我想按两个、四个或六个月的时间段汇总 R 中的动物园数据。这种类型的日期处理只有两个可用的选项,使用:

a) as.yearmon => 处理按月分组的每日数据

b) as.yearqtr => 处理按 3 个月的固定组(一月-三月、四月-六月、七月-设置和十月-十二月)分组的每日数据。

一个最小的例子

library(zoo)        
# creating a vector of Dates 
dt = as.Date(c("2001-01-01","2001-01-02","2001-04-01","2001-05-01","2001-07-01","2001-10-01"),
             "%Y-%m-%d")
# the original dates        
dt
[1] "2001-01-01" "2001-01-02" "2001-04-01" "2001-05-01" "2001-07-01" "2001-10-01"

# conversion to monthly data
as.yearmon(dt)
[1] "jan 2001" "jan 2001" "abr 2001" "mai 2001" "jul 2001" "out 2001"

# conversion to quarterly data
as.yearqtr(dt)
[1] "2001 Q1" "2001 Q1" "2001 Q2" "2001 Q2" "2001 Q3" "2001 Q4"

set.seed(0)
# irregular time series
daily_db = zoo(matrix(rnorm(3 * length(dt)),
                    nrow = length(dt),
                    ncol = 3),
             order.by = dt)
daily_db                                                
2001-01-01  1.2629543 -0.928567035 -1.1476570
2001-01-02 -0.3262334 -0.294720447 -0.2894616
2001-04-01  1.3297993 -0.005767173 -0.2992151
2001-05-01  1.2724293  2.404653389 -0.4115108
2001-07-01  0.4146414  0.763593461  0.2522234
2001-10-01 -1.5399500 -0.799009249 -0.8919211

# data aggregated by month
aggregate(daily_db,as.yearmon,sum)
                 V1           V2         V3
jan 2001  0.9367209 -1.223287482 -1.4371186
abr 2001  1.3297993 -0.005767173 -0.2992151
mai 2001  1.2724293  2.404653389 -0.4115108
jul 2001  0.4146414  0.763593461  0.2522234
out 2001 -1.5399500 -0.799009249 -0.8919211

# data aggregated by quarter
aggregate(daily_db,as.yearqtr,sum)
                V1         V2         V3
2001 Q1  0.9367209 -1.2232875 -1.4371186
2001 Q2  2.6022286  2.3988862 -0.7107260
2001 Q3  0.4146414  0.7635935  0.2522234
2001 Q4 -1.5399500 -0.7990092 -0.8919211

我想定义如下函数:

as.yearperiod = function(x, period = 6) {...} # convert dates in semesters

使用这种方式:

# data aggregated by semester
aggregate(base_dados_diaria, as.yearperiod, period = 6, sum)

我希望得到这样的结果:

                V1         V2         V3
2001 S1  3.538950   1.175599  -2.147845
2001 S2 -1.125309  -0.035416  -0.639698

【问题讨论】:

  • 您有问题吗?看起来你没有。
  • 有些不对劲。您的数据,将其汇总数月和按季度汇总是相同的数据!我想你应该调查一下
  • 再次检查上面生成的数据。在矩阵中,你说 nrow=length(dt) length(dt) =4 但你想出了一个有 5 行的矩阵.. 怎么样???
  • 我修复了 dt 对象@Onyambu。谢谢。
  • 对不起我的英语@InfiniteFlashChess。我会改标题的。

标签: r date zoo as.yearqtr


【解决方案1】:

先生,我建议您使用lubridate 包来处理自定义日期间隔。申请floor_date,您的任务就可以轻松完成,如下:

six_m_interval <- lubridate::floor_date( dt , "6 months" )
# [1] "2001-01-01" "2001-01-01" "2001-01-01" "2001-01-01" "2001-07-01" "2001-07-01"

aggregate( daily_db , six_m_interval , sum )
#                  V1          V2         V3
# 2001-01-01  3.538950  1.17559873 -2.1478445
# 2001-07-01 -1.125309 -0.03541579 -0.6396977

【讨论】:

    【解决方案2】:

    日期2期间

    Date2period 输入一个"Date" 对象并返回一个表示句点(学期等)的字符串,具体取决于参数period 的值,它应该是一个除数为12 的数字。它在内部转换到yearmon,然后提取年份和周期,即月份,并从中生成所需的字符串。

    Date2period <- function(x, period = 6, sep = " S") {
      ym <- as.yearmon(x)
      paste(as.integer(ym), (cycle(ym) - 1) %/% period + 1, sep = sep)
    }
    

    测试上述内容:

    library(zoo)
    
    # inputs
    period <- 6
    dt <- as.Date(c("2001-01-01","2001-04-01","2001-07-01","2001-10-01"))
    
    Date2period(dt)
    ## [1] "2001 S1" "2001 S1" "2001 S2" "2001 S2"
    
    aggregate(daily_db, Date2period, sum)
    ##                V1        V2          V3
    ## 2001 S1 0.9367209 -1.125309  2.39888622
    ## 2001 S2 2.6022286 -1.223287 -0.03541579
    

    period2yearmon, period2Date

    以下是其他转换函数,但用于其他方向:

    period2yearmon <- function(x, period = 6) {
         year <- as.numeric(sub("\\D.*", "", x))
         cyc <- as.numeric(sub(".*\\D", "", x))
         as.yearmon(year + period * (cyc - 1) / 12)
    }
    
    period2Date <- function(x, period = 6) as.Date(period2yearmon(x, period))
    

    以下是对这些功能的一些测试。由于从 Date 转换为 period 并返回 Date 给出了输入日期所在的期间的开始日期,因此我们在末尾显示了 aggregate 的效果。

    # create a period string
    d <- Date2period(dt)
    ## [1] "2001 S1" "2001 S1" "2001 S2" "2001 S2"
    
    period2yearmon(d)
    ## [1] "Jan 2001" "Jan 2001" "Jul 2001" "Jul 2001"
    
    period2Date(d)
    ## [1] "2001-01-01" "2001-01-01" "2001-07-01" "2001-07-01"
    
    aggregate(daily_db, function(x) period2Date(Date2period(x)), sum)
    ##                   V1        V2          V3
    ## 2001-01-01 0.9367209 -1.125309  2.39888622
    ## 2001-07-01 2.6022286 -1.223287 -0.03541579
    

    这可以通过创建诸如yearmon 之类的 S3 对象来变得更加复杂,但出于问题中所示的目的,这并不是真正需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2020-01-08
      • 2018-10-24
      • 2014-03-21
      • 1970-01-01
      相关资源
      最近更新 更多