将 xts 转换为 tibble 的最佳方法是什么

What is the best way to transform an xts into a tibble

从 tibble 包版本 2.0.1 开始,将 xts 对象转换为 tibble 的最佳方法是什么? 考虑以下示例

library(tibble)
library(xts)

myxts <- xts(matrix(1:4, 2, 2), order.by = seq.Date(from = as.Date("2019-02-26"), length.out = 2, by = "d"))

as_tibble(myxts)

这会发出警告:

Warning message: Calling as_tibble() on a vector is discouraged, because the behavior is likely to change in the future. Use enframe(name = NULL) instead.

但是使用 enframe 会导致错误:

enframe(myxts, name = NULL)

Error: x must not have more than one dimension. length(dim(x)) must be zero or one, not 2.

我知道 timetk 包具有将 xts 对象转换为 tibbles 的功能。然而,这个包是孤立的,所以我宁愿避免它。

感谢您的反馈。

编辑: 我会对这个问题的 tidyverse 解决方案感兴趣:当然可以先将 xts 对象转换为任意对象(例如数据框),然后再转换为 tibble。 但是不应该也有直接的方式吗?

编辑2: 从 tibble 包版本 3.0.3 开始,警告不再出现。 特别是可以使用 Yakov-vc 的答案中的行进行 'tidy' 转换。

使用 fortify.zoo 将其转换为数据框,然后 as.tibble 将其转换为小标题。

myxts %>% fortify.zoo %>% as.tibble

给予:

# A tibble: 2 x 3
  Index          .   ..1
  <date>     <int> <int>
1 2019-02-26     1     3
2 2019-02-27     2     4

更新

由于 tibble 包的变化,如果 myxts 没有名字(或者有 tibble 不喜欢的名字),上面的方法不再有效,所以改用这个:

myxts %>% fortify.zoo %>% as_tibble(.name_repair = "minimal")

另外两个答案建议使用 broom::tidy,尽管这对某些 xts objects 有效,但在问题中与 myxts object 一起使用时会生成错误消息。还有一个答案说 fortify 可以从 ggplot2 中删除导致问题,但如果我们直接调用 fortify.zoo,就像我们在上面的代码行中所做的那样,这段代码将继续工作。

2021 年 3 月 30 日。刚刚用 tibble 3.1.0 重新访问了这个,现在下面的 运行 没有产生错误或警告;但是,缺少索引,因此上面使用 fortify.zoo 仍然是最好的转换方式。

as_tibble(myxts)  # index missing

现在可以使用 broom::tidy() 函数将 xts 对象转换为 tibble,此函数比 ggplot2::fortify() 更受青睐,因为它可能在未来被弃用,per ggplot2::fortify().

的 R 帮助
library(quantmod)
library(broom)

symbol <- getSymbols("AAPL", src = "yahoo", from = as.Date("2014-01-01"),
                     to = as.Date("2014-12-31"),auto.assign=FALSE)
symbol_df <- tidy(symbol)
str(symbol_df)

...输出:

> str(symbol_df)
tibble [1,506 × 3] (S3: tbl_df/tbl/data.frame)
 $ index : Date[1:1506], format: "2014-01-02" "2014-01-02" ...
 $ series: chr [1:1506] "AAPL.Open" "AAPL.High" "AAPL.Low" "AAPL.Close" ...
 $ value : num [1:1506] 1.98e+01 1.99e+01 1.97e+01 1.98e+01 2.35e+08 ...

我会选择继续使用 broom::tidy 函数,通过 nest(index, value) 步骤对其进行扩充,以更好地查看基础数据。请注意 symbol 是 R xts object.

的示例
library(quantmod)
library(broom)
library(tidyverse)

symbol <- getSymbols("AAPL", 
                     src = "yahoo", 
                     from = as.Date("2014-01-01"),
                     to = as.Date("2014-12-31"), 
                     auto.assign=FALSE)

symbol_df <- broom::tidy(symbol) %>% nest(index, value)

symbol_df 现在将在单独的小标题中提供时间序列数据可用的每个类别:

# A tibble: 6 x 2
  series        data              
  <chr>         <list>            
1 AAPL.Open     <tibble [251 x 2]>
2 AAPL.High     <tibble [251 x 2]>
3 AAPL.Low      <tibble [251 x 2]>
4 AAPL.Close    <tibble [251 x 2]>
5 AAPL.Volume   <tibble [251 x 2]>
6 AAPL.Adjusted <tibble [251 x 2]>

此时,如果要查找AAPL.Volume对应的时间序列数据,接下来的步骤如下:

symbol_df %>% 
  filter(series == "AAPL.Volume") %>% 
  pull(data) %>% as.data.frame() %>% as_tibble()

给予

# A tibble: 251 x 2
   index          value
   <date>         <dbl>
 1 2014-01-02 234684800
 2 2014-01-03 392467600
 3 2014-01-06 412610800
 4 2014-01-07 317209200
 5 2014-01-08 258529600
 6 2014-01-09 279148800
 7 2014-01-10 304976000
 8 2014-01-13 378492800
 9 2014-01-14 332561600
10 2014-01-15 391638800
# ... with 241 more rows

怎么样as_tibble(xts) %>% add_column(day = index(xts), .before = 1, )