r中是否可以检查日期列表中的每个日期是否在间隔列表中?

问题描述

我有一个股票行情自动收录器的时间序列。我也有一个数据框,其中有2列代表衰退的开始和结束日期。 我需要创建一个列表,以表示股票时间序列中的每一天是否处于衰退(1)或不是(0)。 因此,更详细地说,我的表格如下所示:

    structure(list(Peak = structure(c(-20819,-18781,-18263,-17047,-15798,-14763,-11933,-9100,-7731,-6028,-4536,-3562,-31,1400,3652,4199,7486,11382,13848,18293),class = "Date"),Trough = structure(c(-20120,-18569,-17716,-16620,-15402,-13455,-11537,-8858,-7397,-5724,-4293,-3256,304,1885,3834,4687,7729,11627,14396,18504),class = "Date")),row.names = 4:23,class = "data.frame")

我尝试过:

getSymbols('NFCI',src = 'FRED')
time(NFCI) %within% interval(recessions$Peak,recessions$Trough)

但是我没有得到正确的答案,并且我也得到了警告

较长的对象长度不是较短的对象长度的倍数

我可以做一个循环并检查每一行,但认为可能会有更简单的方法。 预先感谢!

编辑: 显然,我确实得到了正确的答案,但是我手动地对其进行了错误的测试,因此我认为答案是错误的。感谢@Fernandobarbosa和@RuiBarradas使我注意到它。

enter image description here

解决方法

诀窍是将interval对象强制为类"list"。请参阅help(``%within%``)中的最后一个示例。

library(lubridate)
library(quantmod)

aapl <- getSymbols("AAPL",auto.assign = FALSE)

time(aapl) %within% as.list(interval(recessions$Peak,recessions$Trough))

此编辑旨在回答以下评论。

interval调用的输出是

interval(recessions$Peak,recessions$Trough)
# [1] 1913-01-01 UTC--1914-12-01 UTC 1918-08-01 UTC--1919-03-01 UTC
# [3] 1920-01-01 UTC--1921-07-01 UTC 1923-05-01 UTC--1924-07-01 UTC
# [5] 1926-10-01 UTC--1927-11-01 UTC 1929-08-01 UTC--1933-03-01 UTC
# [7] 1937-05-01 UTC--1938-06-01 UTC 1945-02-01 UTC--1945-10-01 UTC
# [9] 1948-11-01 UTC--1949-10-01 UTC 1953-07-01 UTC--1954-05-01 UTC
#[11] 1957-08-01 UTC--1958-04-01 UTC 1960-04-01 UTC--1961-02-01 UTC
#[13] 1969-12-01 UTC--1970-11-01 UTC 1973-11-01 UTC--1975-03-01 UTC
#[15] 1980-01-01 UTC--1980-07-01 UTC 1981-07-01 UTC--1982-11-01 UTC
#[17] 1990-07-01 UTC--1991-03-01 UTC 2001-03-01 UTC--2001-11-01 UTC
#[19] 2007-12-01 UTC--2009-06-01 UTC 2020-02-01 UTC--2020-08-30 UTC

它成为列表

as.list(interval(recessions$Peak,recessions$Trough))
#[[1]]
#[1] 1913-01-01 UTC--1914-12-01 UTC
#
#[[2]]
#[1] 1918-08-01 UTC--1919-03-01 UTC
#
#[[3]]
#[1] 1920-01-01 UTC--1921-07-01 UTC
#
#[[4]]
#[1] 1923-05-01 UTC--1924-07-01 UTC
#
#[[5]]
#[1] 1926-10-01 UTC--1927-11-01 UTC
#
#[[6]]
#[1] 1929-08-01 UTC--1933-03-01 UTC
#
#[[7]]
#[1] 1937-05-01 UTC--1938-06-01 UTC
#
#[[8]]
#[1] 1945-02-01 UTC--1945-10-01 UTC
#
#[[9]]
#[1] 1948-11-01 UTC--1949-10-01 UTC
#
#[[10]]
#[1] 1953-07-01 UTC--1954-05-01 UTC
#
#[[11]]
#[1] 1957-08-01 UTC--1958-04-01 UTC
#
#[[12]]
#[1] 1960-04-01 UTC--1961-02-01 UTC
#
#[[13]]
#[1] 1969-12-01 UTC--1970-11-01 UTC
#
#[[14]]
#[1] 1973-11-01 UTC--1975-03-01 UTC
#
#[[15]]
#[1] 1980-01-01 UTC--1980-07-01 UTC
#
#[[16]]
#[1] 1981-07-01 UTC--1982-11-01 UTC
#
#[[17]]
#[1] 1990-07-01 UTC--1991-03-01 UTC
#
#[[18]]
#[1] 2001-03-01 UTC--2001-11-01 UTC
#
#[[19]]
#[1] 2007-12-01 UTC--2009-06-01 UTC
#
#[[20]]
#[1] 2020-02-01 UTC--2020-08-30 UTC

在下面的返回值中有522 TRUE个值:

in_recess <- time(aapl) %within% as.list(interval(recessions$Peak,recessions$Trough))
sum(in_recess)
#[1] 522
,

正如Rui所说,“ as.list”应该可以解决您的问题。代码是:

library(lubridate)
library(quantmod)
getSymbols('NFCI',src = 'FRED')
time(NFCI) %within% as.list(interval(recessions$Peak,recessions$Trough))

如果要将虚拟对象移动到NFCI,可以执行以下操作:

NFCI$isRecession <- time(NFCI) %within% as.list(interval(recessions$Peak,recessions$Trough))

附录:我为复制数据而编写的完整代码。运行正常。

library(quantmod)
library(lubridate)


peak = c(-20819,-18781,-18263,-17047,-15798,-14763,-11933,-9100,-7731,-6028,-4536,-3562,-31,1400,3652,4199,7486,11382,13848,18293)

trough = c(-20120,-18569,-17716,-16620,-15402,-13455,-11537,-8858,-7397,-5724,-4293,-3256,304,1885,3834,4687,7729,11627,14396,18504)


recessions <- data.frame(Peak=as.Date(peak),Trough=as.Date(trough)
) 



getSymbols('NFCI',recessions$Trough))

NFCI$isRecession <- time(NFCI) %within% as.list(interval(recessions$Peak,recessions$Trough))