根据数据框中可能包含或不包含的日期过滤数据框

时间:2016-10-18 05:30:43

标签: r date dplyr

我有一个如下所示的数据框(df):

    derv        market       date
 -10.7803563 S&P 500 Index 2008-01-02
 -15.6922552 S&P 500 Index 2008-01-03
 -15.7648483 S&P 500 Index 2008-01-04
 -10.2294744 S&P 500 Index 2008-01-07
  -0.5918593 S&P 500 Index 2008-01-08
   8.1518987 S&P 500 Index 2008-01-09
 .....
  84.1518987 S&P 500 Index 2014-12-31

我希望在特定日期之前找到df中的10个交易日。例如,2008-01-12。

我想过如下使用dplyr:

df %>% select(derv,Market,date) %>%
            filter(date > 2008-01-12 - 10 & Date <2008-01-12)

但我遇到的问题是关于如何在特定日期之前的10个交易日编制索引。上面的代码不起作用,我不知道在使用dplyr的情况下如何处理它。

另一个相关问题是特定日期(例如2008-01-12)可能是也可能不是df。如果具体是在df,我想我只需要回去9天算一下;但它不是df,我需要回到10个指数。我不确定这里是否正确,但这是让我困惑的部分。

非常感谢任何见解。

2 个答案:

答案 0 :(得分:3)

使用dplyrdata.table::rleid()
示例数据:

set.seed(123)
df=data.frame(derv=rnorm(18),Date=as.Date(c(1,2,3,4,6,7,9,11,12,13,14,15,18,19,20,21,23,24),origin="2008-01-01"))

创建具有索引的列,以便在所选日期之前选择不超过10天。

library(dplyr)
library(data.table)
df %>%
  filter(Date < "2008-01-19") %>%
  mutate(id = rleid(Date)) %>%
  filter(id > (max(id)-10)) %>%
  ungroup() %>%
  select(derv,Date)

         derv       Date
1  -1.0678237 2008-01-04
2  -0.2179749 2008-01-05
3  -1.0260044 2008-01-07
4  -0.7288912 2008-01-08
5  -0.6250393 2008-01-10
6  -1.6866933 2008-01-12
7   0.8377870 2008-01-13
8   0.1533731 2008-01-14
9  -1.1381369 2008-01-15
10  1.2538149 2008-01-16

编辑: Procrastinatus Maximus的解决方案更短,只需要dplyr

df %>% filter(Date < "2008-01-19") %>% filter(row_number() > (max(row_number())-10))

这给出了相同的输出。

答案 1 :(得分:1)

所以这个问题的答案实际上取决于你的日期在R中的存储方式。但是让我们假设ISO 8601,它是基于你的代码的样子。

首先让我们制作一些数据。

    mydates <- as.Date("2007-06-22")
    mydates<-c(mydates[1]+1:11, mydates[1]+14:19)

    StockPrice<-c(1:17)

    df<-data.frame(mydates,StockPrice)

然后指定感兴趣的日期,如@stats_guy

    dateofinterest<-as.Date("2007-07-11")

我会说使用子集,只是从你的日期中减去11,因为它已经是那种格式。

    foo<-subset(df, mydates<dateofinterest & mydates>(dateofinterest-11))

然后你将有10天的漂亮时间,但我不确定你是否想要10个交易日?或者连续10天,即使这意味着您的价格列表可能<&lt; 10.我故意使我的数据集像真实的市场数据一样,以说明这一点。所以我在10天内得出了8个值,而不是10个。有兴趣听听你真正想要的东西。

假设您实际上在寻找10个交易日。只是成为魔鬼的拥护者,你可以假设不会有超过10天没有交易。因此,我们会在您感兴趣的日期之前回溯20天。

    foo<-subset(df, mydates<dateofinterest & mydates>(dateofinterest-20))

然后我们使用if语句检查您的数据子集,以查看其中是否有超过10个交易日。如果有超过10行,那么你有太多天。我们只是将子集数据foo修剪为从底部(最新日期)开始的正确长度,然后从那里计算9个条目。现在你在一个漂亮的整洁数据集中有十个交易日。

    if (nrow(foo)>10){
    foo<-foo[(nrow(foo)-9):(nrow(foo)),]
    }