如何使用 `tempdisagg` 包中的 `td` 命令将每月数据分解为每日数据频率?

Posted

技术标签:

【中文标题】如何使用 `tempdisagg` 包中的 `td` 命令将每月数据分解为每日数据频率?【英文标题】:How can I use the `td` command from the `tempdisagg` package to disaggregate monthly data into daily data frequency? 【发布时间】:2020-04-12 12:27:54 【问题描述】:

我有一个每月频率数据,我试图将其分解为每日频率数据。 所以我使用R中tempdisagg包中的td命令,使用下面的代码:

 dat=ts(data[,2])
 result=td(dat~1, conversion = "average", to = "day", method = "chow-lin-maxlog")

然后我收到以下错误消息:

 Error in td(dat ~ 1, conversion = "average", to = "day", method = "chow-lin-maxlog") : 'to' argument: unknown character string

我用于dat的数据如下:

 > dput(head(dat))
 c(82.47703009, 84.63094431, 70.00659987, 78.81135651, 74.749746,82.95638213)

所以虽然这个数据dat 是每月频率,但开始和结束还没有反映这一点。 实际上,开始日期是 1/1997,结束日期是 9/2019。

我可以帮助我将这个月度数据dat 分解为每日频率数据吗?

【问题讨论】:

Eric,你能提供可用格式的数据吗?请不要发布代码/数据/错误的图像:它不能被复制或搜索 (SEO),它会破坏屏幕阅读器,并且它可能不适合某些移动设备。参考:meta.***.com/a/285557/3358272(和xkcd.com/2116)。请直接包含数据(例如,dput(head(x))data.frame(...))。谢谢! 我添加了 dput(head(x)) 东西。现在可以了吗? 这很奇怪。如果我做dput(ts(head(1:50))),那么我会得到structure(1:6, .Tsp = c(1, 6, 1), class = "ts")。您的图像表明您的 dat 是时间序列,但您的 c(...) 不是。这两个dats 是一样的吗? 是的,这两个数据是一样的。数据和dat不同。 当我查看tempdisagg.pdf时,我在任何地方都找不到"daily",而to=说它支持“作为字符串的高频目的地频率(“季度”或“每月") 或标量(例如 2、4、7、12)"。哪里建议支持to="daily"?你可以试试to=1吗? (除此之外我真的帮不上什么忙。我不太了解这个包,以为我可以提供一般帮助。) 【参考方案1】:

看起来 tempdisagg 包不允许每月到每天的分解。来自td() 帮助文件的“to”参数:

作为字符串(“季度”或“月度”)或标量(例如 2、4、7、12)的高频目标频率。如果输入序列是 ts 对象,则如果没有给出指示符,则该参数是必需的。如果输入序列是向量,to 必须是表示频率比的标量。

您的错误消息“'to' argument: unknown character string”是因为 to = 参数只接受 ' Quarterly' 或 'monthly' 作为字符串。

这里有一些关于将每月数据分解为每日统计数据堆栈交换的讨论:https://stats.stackexchange.com/questions/258810/disaggregate-monthly-forecasts-into-daily-data

经过一番搜索,似乎没有人一直使用按月到每日分类的数据。 tempdisagg 包似乎能够完成大多数其他人认为可能的事情——每年到每季度或每月,以及一致的甚至倍数的时间段。

埃里克,我在下面添加了一个脚本,据我了解,该脚本应该说明您正在尝试做的事情。

这里我们使用真实定价数据从每日价格 -> 每月价格 -> 每月回报 -> 平均每日回报。

library(quantmod)
library(xts)
library(zoo)
library(tidyverse)
library(lubridate)

# Get price data to use as an example
getSymbols('MSFT')

#This data has more information than we want, remove unwanted columns:
msft <- Ad(MSFT) 

#Add new column that acts as an 'indexed price' rather than 
# actual price data.  This is to show that calculated returns
# don't depend on real prices, data indexed to a value is fine.
msft$indexed <- scale(msft$MSFT.Adjusted, center = FALSE)

#split into two datasets  
msft2 <- msft$indexed
msft$indexed <- NULL


#msft contains only closing data, msft2 only contains scaled data (not actual prices)
#  move from daily data to monthly, to replicate the question's situation.
a <- monthlyReturn(msft)
b <- monthlyReturn(msft2)

#prove returns based on rescaled(indexed) data and price data is the same:
all.equal(a,b)

# subset to a single year
a <- a['2019']
b <- b['2019']

#add column with days in each month
a$dim <- days_in_month(a) 
a$day_avg <- a$monthly.returns / a$dim  ## <- This must've been left out

day_avgs <- data.frame(day_avg = rep(a$day_avg, a$dim))


# daily averages timesereis from monthly returns.
z <- zoo(day_avgs$day_avg, 
         seq(from = as.Date("2019-01-01"), 
             to = as.Date("2019-12-31"), 
             by = 1)) %>%
  as.xts()

#chart showing they are the same:
PerformanceAnalytics::charts.PerformanceSummary(cbind(a$monthly.returns, z))

这里是三个图表,显示 1. 仅每月回报,2. 每月回报的日平均值,3. 两者一起。由于它们是相同的,因此第三张图像中的过度绘图仅显示了一个。

【讨论】:

就我而言,每月数字是平均值,而不是您的问题帖子询问的总和。例如,我的数据显示 1 月份的平均值为 4%。如果我想转换为每日数据,我目前正在考虑在 1 月 1 日立即使用这 4%,依此类推。但不确定这样做是否仍然可以。 请问您对此案是否有任何想法(正如我发布的问题所询问的那样)? 从您发布的数据中不清楚您有费率,它看起来像价格。您在评论中提到,您 1 月份的平均利率确实为 0.04。如果您要从月平均费率 -> 日平均费率出发,普遍接受的原则是月费率 / 30(我认为)。对于您在 1 月份提到的 0.04 (4%),每日费率为 0.04/30 或 ~.001315。如果你能为我澄清你的问题,那可能会有所帮助。您有价格数据或费率数据吗?你期待的结果是什么?无论哪种方式, id 看起来都不像 tempdisagg 是解决方案。 我发布的数据是以100为基准的月度指数。因为是索引,所以不加起来。 好的。如果您对百分比数据(回报)感兴趣并且拥有定期时间序列中的价格数据,您可以使用quantmod::monthlyReturnPerformanceAnalytics::Return.calculate 获取(每月)回报。从那里如果您需要假设每日回报,您可以使用上述(评论)方法。【参考方案2】:

使用 tempdisagg 1.0,可以轻松地将月度数据分解为每日数据,使总和或平均值与月度序列保持一致。

post 更详细地解释了新功能。

A bit of trickery 还可以从每月转换为每周。

这是一个可重现的示例,使用原始帖子的前六个月:

x <- tsbox::ts_tbl(ts(c(82.47703009, 84.63094431, 70.00659987, 78.81135651, 74.749746, 82.95638213), start = 2020, frequency = 12))
x
#> # A tibble: 6 x 2
#>   time       value
#>   <date>     <dbl>
#> 1 2020-01-01  82.5
#> 2 2020-02-01  84.6
#> 3 2020-03-01  70.0
#> 4 2020-04-01  78.8
#> 5 2020-05-01  74.7
#> 6 2020-06-01  83.0

library(tempdisagg)
packageVersion("tempdisagg")
#> [1] '1.0'

m <- td(x ~ 1, to = "daily", method = "fast", conversion = "average")
predict(m)
#> # A tibble: 182 x 2
#>    time       value
#>    <date>     <dbl>
#>  1 2020-01-01  80.6
#>  2 2020-01-02  80.7
#>  3 2020-01-03  80.7
#>  4 2020-01-04  80.7
#>  5 2020-01-05  80.8
#>  6 2020-01-06  80.8
#>  7 2020-01-07  80.9
#>  8 2020-01-08  81.0
#>  9 2020-01-09  81.1
#> 10 2020-01-10  81.2
#> # … with 172 more rows

由reprex package (v2.0.0) 于 2021 年 7 月 15 日创建

【讨论】:

以上是关于如何使用 `tempdisagg` 包中的 `td` 命令将每月数据分解为每日数据频率?的主要内容,如果未能解决你的问题,请参考以下文章

我如何使用javascript循环遍历td中的表[关闭]

如何使用jQuery将Class添加到表内每个tr中的第一个td

如何使用 XSL 在 XML 中的特定 td 中保留新行和空白

如何在 R 包中正确使用其他包中的函数

如何使用 Maven 运行特定包中的所有测试?

如何使用 R 中“ivprobit”包中的“ivprobit”功能?