如何将quantmod的viewfin函数返回的季度数据转换为月度时间序列?

时间:2021-07-01 12:38:24

...either spline- (best) or linear-interpolated (OK) or just repeated values (fine) throughout the quarter. The issue is that I do not know how to convert the data type returned by getFin() and viewFin() into something timeSeries-type usable. Here is my code:

......在整个季度中,样条曲线(最佳)或线性插值(OK)或仅重复值(精细)。问题是我不知道如何将getFin()和viewFin()返回的数据类型转换为timeSeries类型可用的东西。这是我的代码:

getFin('F')
x <- viewFin(F.f, "BS", period="Q")["Total Common Shares Outstanding",]*1000

My desired output is

我想要的输出是

> x
GMT     x.ts
2011-09-01  3816000
2011-08-01  3816000
2011-07-01  3816000
2011-06-01  3815000
2011-05-01  3815000
2011-04-01  3815000
2011-03-01  3813000
2011-02-01  3813000
2011-01-01  3813000
2010-12-01  3778000
2010-11-01  3778000
2010-10-01  3778000
2010-09-01  3484000

However, here is some actual output:

但是,这里有一些实际输出:

> x
2011-09-30 2011-06-30 2011-03-31 2010-12-31 2010-09-30 
   3816000    3815000    3813000    3778000    3484000 
> str(x)
 Named num [1:5] 3816000 3815000 3813000 3778000 3484000
 - attr(*, "names")= chr [1:5] "2011-09-30" "2011-06-30" "2011-03-31" "2010-12-31" ...

It looks like the x object is in some strange reverse format, where the key is the numeric value, and the value is a character string of the date. When I try to extract dates, or the numeric component, I cannot isolate the numeric portion to generate a time series object.

看起来x对象是一些奇怪的反向格式,其中键是数值,值是日期的字符串。当我尝试提取日期或数字组件时,我无法隔离数字部分以生成时间序列对象。

Ideally, to get to my desired output, I would be able to say

理想情况下,为了得到我想要的输出,我可以说

mydates <- timeSequence(from = "2011-01-01", to=Sys.Date(), by = "month")
series <- timeSeries(x$data, mydates)

But I can't seem to extract the numeric data portion.

但我似乎无法提取数字数据部分。

UPDATE

From here and here, I adapted the following code:

从这里到这里,我改编了以下代码:

getFin('F')
x <- viewFin(F.f, "BS", period="Q")["Total Common Shares Outstanding",]*1000
zoox = zoo(x, order.by=as.Date(names(x)))
x2 <- na.spline(merge(zoox, foo=zoo(NA, order.by=seq(start(zoox), end(zoox), "month")))[, 1])

However, my output mangles the dates a bit and messes up the interpolation:

但是,我的输出会稍微破坏日期并使插值变得混乱:

>x2
2010-09-30 2010-10-30 2010-11-30 2010-12-30 2010-12-31 2011-01-30 2011-03-02 
   3484000    3623591    3720509    3776671    3778000    3804738    3813071 
2011-03-30 2011-03-31 2011-04-30 2011-05-30 2011-06-30 2011-07-30 2011-08-30 
   3813025    3813000    3813100    3814116    3815000    3814976    3814884 
2011-09-30 
   3816000 

As you can see, I have both 12-30 and 12-31, 3 values for March-2011, but no February, etc. How to solve this?

正如你所看到的,我有2011年3月的12-30和12-31,3个值,但没有2月等。如何解决这个问题?

2 个解决方案

#1


1  

I just had this same problem -- i wrote two functions to make it happen.

我只是遇到了同样的问题 - 我写了两个函数来实现它。

First, you want a date function to move dates about, as you probably want month end dates but R deals with first-of dates much more simply.

首先,您需要一个日期函数来移动日期,因为您可能需要月末日期,但R更简单地处理第一个日期。

Date Functions

toLastDay <- function(dateObj, monAdv=0, ToFirst = FALSE)
# takes date object, transforms and returns a dat object
{
  tt <- as.POSIXlt(dateObj)
  tt$mon <- tt$mon + monAdv # moves the month
  tt$mday <- 1L             # make date the first
  if(ToFirst) {             
      tt <- as.Date(tt)
  } else { 
      tt$mon <- tt$mon + 1L # go to the first of the next month
      tt <- as.Date(tt) - 1L # subtract one day, yielding the last of prior month
  }
  return(tt)
}

Now you want a function that take the data and does a linear interp -- i use the na.approx function in zoo and xts. Here you probably want mid-qtr dates -- most qtrly data is best thought of as mid-qtr in my experience.

现在你想要一个获取数据并执行线性插入的函数 - 我在zoo和xts中使用na.approx函数。在这里你可能想要中期qtr日期 - 根据我的经验,大多数qtrly数据最好被认为是qtr中期。

# make Qtrly monthly -- with obsv in the mid qtr
qtr2Mon <- function(QD) 
{
    fromD <- toLastDay(index(first(QD)), -2L, ToFirst = TRUE)
    toD <- toLastDay(index(last(QD)), ToFirst = TRUE)
    q2m_dates <- toLastDay(seq(fromD, toD, by = 'mon'))
    emptyX <- xts(, q2m_dates)
    QD_adj <- QD
    index(QD_adj) <- toLastDay(index(QD), monAdv = -1L)
    mm <- merge(emptyX, QD_adj)
    mm_filled <- na.approx(mm)
    return(mm_filled)
}

First we make a qtrly xts object -- think of it as qtrly GDP or some such

首先,我们制作一个qtsly xts对象 - 将其视为qtrly GDP或其他类似物

Sys.setenv(TZ = 'GMT')
require(xts)

qdates <- seq(as.Date("2000-03-01"), as.Date("2013-06-01"), by = "3 mon")
qdates <- toLastDay(qdates)
qdata <- rnorm(length(qdates), mean = 1)
qtr_XTS <- xts(qdata, order.by = qdates)

Now we can use the above library functions to convert it to monthly, assuming linear growth etc.

现在我们可以使用上面的库函数将其转换为每月,假设线性增长等。

mon_fromQtr <- qtr2Mon(qtr_XTS)

done!

#2


0  

UPDATE 2:

Please post a better answer! This is really ugly, but here's how I got something acceptable:

请发布更好的答案!这真的很难看,但这就是我接受的东西:

getFin('F')
x <- viewFin(F.f, "BS", period="Q")["Total Common Shares Outstanding",]*1000
zoox = zoo(x, order.by=as.Date(names(x)))
foo=zoo(NA, order.by=seq(as.Date(as.character(timeFirstDayInMonth(start(zoox)))), as.Date(as.character(timeFirstDayInMonth(end(zoox)))), "month"))
foo2 <- na.approx(merge(zoox, foo)[, 1])
fx <- merge(foo2,foo, all=FALSE)[,1]

Which converts

> x
2011-09-30 2011-06-30 2011-03-31 2010-12-31 2010-09-30 
   3816000    3815000    3813000    3778000    3484000 

into

> fx
2010-10-01 2010-11-01 2010-12-01 2011-01-01 2011-02-01 2011-03-01 2011-04-01 
   3487196    3586261    3682130    3778389    3790444    3801333    3813022 
2011-05-01 2011-06-01 2011-07-01 2011-08-01 2011-09-01 
   3813681    3814363    3815011    3815348    3815685 

I find this too ugly to be true, so I post this answer, but want someone else to post a handsomer one.

我发现这太难看了,所以我发布了这个答案,但是希望别人发布一个简洁的答案。

#1


1  

I just had this same problem -- i wrote two functions to make it happen.

我只是遇到了同样的问题 - 我写了两个函数来实现它。

First, you want a date function to move dates about, as you probably want month end dates but R deals with first-of dates much more simply.

首先,您需要一个日期函数来移动日期,因为您可能需要月末日期,但R更简单地处理第一个日期。

Date Functions

toLastDay <- function(dateObj, monAdv=0, ToFirst = FALSE)
# takes date object, transforms and returns a dat object
{
  tt <- as.POSIXlt(dateObj)
  tt$mon <- tt$mon + monAdv # moves the month
  tt$mday <- 1L             # make date the first
  if(ToFirst) {             
      tt <- as.Date(tt)
  } else { 
      tt$mon <- tt$mon + 1L # go to the first of the next month
      tt <- as.Date(tt) - 1L # subtract one day, yielding the last of prior month
  }
  return(tt)
}

Now you want a function that take the data and does a linear interp -- i use the na.approx function in zoo and xts. Here you probably want mid-qtr dates -- most qtrly data is best thought of as mid-qtr in my experience.

现在你想要一个获取数据并执行线性插入的函数 - 我在zoo和xts中使用na.approx函数。在这里你可能想要中期qtr日期 - 根据我的经验,大多数qtrly数据最好被认为是qtr中期。

# make Qtrly monthly -- with obsv in the mid qtr
qtr2Mon <- function(QD) 
{
    fromD <- toLastDay(index(first(QD)), -2L, ToFirst = TRUE)
    toD <- toLastDay(index(last(QD)), ToFirst = TRUE)
    q2m_dates <- toLastDay(seq(fromD, toD, by = 'mon'))
    emptyX <- xts(, q2m_dates)
    QD_adj <- QD
    index(QD_adj) <- toLastDay(index(QD), monAdv = -1L)
    mm <- merge(emptyX, QD_adj)
    mm_filled <- na.approx(mm)
    return(mm_filled)
}

First we make a qtrly xts object -- think of it as qtrly GDP or some such

首先,我们制作一个qtsly xts对象 - 将其视为qtrly GDP或其他类似物

Sys.setenv(TZ = 'GMT')
require(xts)

qdates <- seq(as.Date("2000-03-01"), as.Date("2013-06-01"), by = "3 mon")
qdates <- toLastDay(qdates)
qdata <- rnorm(length(qdates), mean = 1)
qtr_XTS <- xts(qdata, order.by = qdates)

Now we can use the above library functions to convert it to monthly, assuming linear growth etc.

现在我们可以使用上面的库函数将其转换为每月,假设线性增长等。

mon_fromQtr <- qtr2Mon(qtr_XTS)

done!

#2


0  

UPDATE 2:

Please post a better answer! This is really ugly, but here's how I got something acceptable:

请发布更好的答案!这真的很难看,但这就是我接受的东西:

getFin('F')
x <- viewFin(F.f, "BS", period="Q")["Total Common Shares Outstanding",]*1000
zoox = zoo(x, order.by=as.Date(names(x)))
foo=zoo(NA, order.by=seq(as.Date(as.character(timeFirstDayInMonth(start(zoox)))), as.Date(as.character(timeFirstDayInMonth(end(zoox)))), "month"))
foo2 <- na.approx(merge(zoox, foo)[, 1])
fx <- merge(foo2,foo, all=FALSE)[,1]

Which converts

> x
2011-09-30 2011-06-30 2011-03-31 2010-12-31 2010-09-30 
   3816000    3815000    3813000    3778000    3484000 

into

> fx
2010-10-01 2010-11-01 2010-12-01 2011-01-01 2011-02-01 2011-03-01 2011-04-01 
   3487196    3586261    3682130    3778389    3790444    3801333    3813022 
2011-05-01 2011-06-01 2011-07-01 2011-08-01 2011-09-01 
   3813681    3814363    3815011    3815348    3815685 

I find this too ugly to be true, so I post this answer, but want someone else to post a handsomer one.

我发现这太难看了,所以我发布了这个答案,但是希望别人发布一个简洁的答案。