【问题标题】:How do you return the "period" part of to a time series?您如何将“周期”部分返回到时间序列?
【发布时间】:2017-07-19 20:44:39
【问题描述】:

R 中,您可以使用cycle() 函数轻松返回时间序列对象的cycle 部分。例如。

> series <- ts(1:50, frequency = 4, start = 2011)
> cycle(series)
     Qtr1 Qtr2 Qtr3 Qtr4
2011    1    2    3    4
2012    1    2    3    4
2013    1    2    3    4
2014    1    2    3    4
2015    1    2    3    4
2016    1    2    3    4
2017    1    2    3    4
2018    1    2    3    4
2019    1    2    3    4
2020    1    2    3    4
2021    1    2    3    4
2022    1    2    3    4
2023    1    2   

但是,我从来没有找到一种干净的方式来返回“期间”部分(例如,季度数据的年份)。大多数情况下,你可以做一个简单的:

> floor(time(series))
     Qtr1 Qtr2 Qtr3 Qtr4
2011 2011 2011 2011 2011
2012 2012 2012 2012 2012
2013 2013 2013 2013 2013
2014 2014 2014 2014 2014
2015 2015 2015 2015 2015
2016 2016 2016 2016 2016
2017 2017 2017 2017 2017
2018 2018 2018 2018 2018
2019 2019 2019 2019 2019
2020 2020 2020 2020 2020
2021 2021 2021 2021 2021
2022 2022 2022 2022 2022
2023 2023 2023 

但是,为了获取年份,我发现对于某些数据(通常是高频数据),errors in floating point precision 会导致一个周期的第一个时间点返回上一周期的值(例如,它是被存储为 2010.9999999 而不是 2011 所以floor() 返回 2010)。我们可以人为地将问题引入数据中:

> seriesprec <- ts(1:50, frequency = 4, start = 2010.999999999999)
> floor(time(seriesprec))
     Qtr1 Qtr2 Qtr3 Qtr4
2011 2010 2011 2011 2011
2012 2011 2012 2012 2012
2013 2012 2013 2013 2013
2014 2013 2014 2014 2014
2015 2014 2015 2015 2015
2016 2015 2016 2016 2016
2017 2016 2017 2017 2017
2018 2017 2018 2018 2018
2019 2018 2019 2019 2019
2020 2019 2020 2020 2020
2021 2020 2021 2021 2021
2022 2021 2022 2022 2022
2023 2022 2023    

现在我们看到浮点精度正在抛出返回值,即使:

> all.equal(time(seriesprec), time(series))
[1] TRUE

我发现似乎可以处理这些边缘情况的最简单的解决方案是:

round(time(series) - (cycle(series) - 1)*deltat(series))

但这对于一个非常简单的任务来说似乎是相当复杂的代码。特别是当cycle() 是一个基函数时,似乎应该有另一个基函数来返回另一半时间定义。

顺便说一句,我知道包可以很好地处理日期和时间,但是由于我所做的很多事情最终都被包装到包中,所以我宁愿不添加像 lubridate 这样的东西作为某些东西的依赖项这可以通过一行(非常麻烦的)基本R 代码来解决。

谢谢!

【问题讨论】:

  • trunc(time(ldeaths))
  • @d.b time() 为时间序列对象返回的对象不属于 timeDate 类,因此 trunc 舍入到特定时间精度的能力没有帮助。相反,它在这种情况下的功能类似于floor(),并且具有与该功能相同的浮点精度问题。
  • 只需添加少量,floor(time(series) + eps) 您可以使用任何合理的小数字作为epseps &lt;- deltat(series) / 2 是一种普遍的可能性。
  • @G.Grothendieck,您也可以使用offset添加少量:floor(time(seriesprec, offset = 0.5))
  • @d.b 您最近的回答似乎有效。您能否写下offset 正在做什么的解释,以便我可以接受它作为答案?

标签: r time-series floating-accuracy


【解决方案1】:

一种方法可能是在获取floortrunc 之前向time 添加一个适当小的值。正如 G.Grothendieck 在 cmets 中提到的,deltat(series)/2 可以是一个合适的小值。并且将offsettime 一起使用可以增加这个小值。来自?time

偏移

可用于指示采样发生的时间 单元。 0(默认)表示单元的开始,0.5 表示中间 和 1 间隔结束。

offset = 0.5 添加到time 相当于添加deltat(series)/2

因此,您应该能够使用

获得正确的句号部分
floor(time(seriesprec, offset = 0.5))

【讨论】:

    猜你喜欢
    • 2016-11-08
    • 2021-05-14
    • 2016-02-19
    • 1970-01-01
    • 2019-03-27
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    相关资源
    最近更新 更多