【问题标题】:How to delete rows for all dates except the last date of the month?如何删除除本月最后一个日期以外的所有日期的行?
【发布时间】:2017-09-19 10:54:04
【问题描述】:

我正在处理 r 中的时间序列,其中包含来自北欧证券交易所的每日观察结果。我只想为每个公司(列)保留一个月的最后一个日期。

我的数据框OSE 看起来像这样(但有数千行和数千列):

Date           Statoil     DNB
1987-09.16     0,21        1,2
1987-09.17     0,22        1,3
1987-09.18     0,15        1,1
1987-09.21     0,16        1,5
1987-09.22     0,27        1,7
1987-09.23     0,28        1,9
1987-09.24     0,30        1,6
1987-09.25     0,32        1,7
1987-09.28     0,29        1,8
1987-09.29     0,33        2,1
1987-09.30     0,34        1,9
1987-10.01     0,37        1,8
1987-10.02     0,38        2,1
1987-10.05     0,34        2,3
1987-10.06     0,28        2,4
1987-10.07     0,27        2,1
1987-10.08     0,25        2,2
1987-10.09     0,21        2,1
1987-10.12     0,31        1,9
1987-10.13     0,31        2,1
1987-10.14     0,32        2,3
1987-10.15     0,37        2,5
1987-10.16     0,41        2,6
1987-10.19     0,51        2,8
1987-10.20     0,62        3,1
1987-10.21     0,59        3,1
1987-10.22     0,58        3,5
1987-10.23     0,61        3,6
1987-10.26     0,62        3,7
1987-10.27     0,63        3,9
1987-10.28     0,57        4,0
1987-10.29     0,54        4,1
1987-10.30     0,64        4,1
1987-11.02     0,66        4,2
1987-11-03     0,67        3,9

我希望它看起来像这样:

Date           Statoil     DNB
1987-09.30     0,34        1,9
1987-10.30     0,64        4,1

你们对删除多余的行有什么建议吗,即不是本月最后日期的行?

非常感谢所有的帮助!

【问题讨论】:

  • “公司”栏在哪里? library(data.table); setDT(df1)[, .SD[which.max(as.IDate(Date, "%Y-%m.%d"))] , .(month = month(as.IDate(Date, "%Y-%m.%d")), Company)]
  • @akrun,我可能在这里解释得有点混乱。每个公司都有自己的专栏(Statoil 是一家,DNB 是另一家,有几千个专栏/公司)。每家公司列中的数字是收盘价(此处使用的数字只是示例)。
  • 如果按月分组,为什么预期输出中没有第11个月的行
  • 我们有 30 年的观察,所以我们实际上应该在操作后得到 360 行。我刚刚添加了第 9 个月和第 10 个月的每个月的最后日期作为示例。实际上,1988年的第11个月、第12个月、第1个月也应该有一行。

标签: r date delete-row


【解决方案1】:

我们可以在 tidyverse 中执行相同的策略,按月份和年份分组:

library(tidyverse)
library(lubridate)

tib$Date <- ymd(tib$Date) # parse .$Date to date class

tib %>% arrange(desc(Date)) %>% # order dates last to first
    group_by(month(Date), year(Date)) %>%
    slice(1)

# A tibble: 3 x 5
# Groups:   month(Date), year(Date) [3]
Date Statoil    DNB `month(Date)` `year(Date)`
<date>  <fctr> <fctr>         <dbl>        <dbl>
1 1987-09-30    0,34    1,9             9         1987
2 1987-10-30    0,64    4,1            10         1987
3 1987-11-03    0,67    3,9            11         1987

【讨论】:

    【解决方案2】:

    在示例中,没有Company 列,因此我们似乎需要按“月”分组并获取max 日期所在的行

    library(data.table)
    setDT(df1)[, Date := as.IDate(Date, "%Y-%m.%d")]
    df1[df1[, .I[which.max(Date)] ,
         .(month = month(Date), year = year(Date))]$V1]
    #         Date Statoil DNB
    #1: 1987-09-30    0,34 1,9
    #2: 1987-10-30    0,64 4,1
    #3: 1987-11-03    0,67 3,9
    

    【讨论】:

    • 这在某种程度上有效,但不完全是我想要的。现在我只得到 12 个日期(过去一年的一个月的最后一个日期)。我希望它给我 360 个日期(过去 30 年每月的最后一个日期)。有没有快速解决方法?
    • 我认为您可能在我发表评论后编辑了您的答案?至少在我发表评论之前我没有注意到编辑。无论如何,我根本没有试图抨击你的答案。我真的很感谢您花时间回答我的问题,但 Nate 的回答奏效了,这是我首先尝试的。因此,这就是我选择接受的答案。我现在也给你的答案投了赞成票!
    • @VegardDyran 不,我没有在您发表评论后更改答案。可能是您在我注销后发表的评论。我之前确实有过编辑 - 只有“月”作为分组变量。然后,我从你的评论中意识到不同的年份并改变了它。无论如何,没问题。感谢 cmets,祝您愉快!
    【解决方案3】:

    您可能需要考虑将数据集转换为 xts 格式,然后使用 to.period() 命令,该命令可以快速轻松地工作。例如,让我们创建一个假的每日时间序列,然后在每个月末对最后一个值进行子集化:

    library(xts)
    set.seed(78)
    date.a <-seq(as.Date("2000/10/1"), as.Date("2000/12/31"), "days")
    dat <-xts(rnorm(length(date.a)), date.a)
    dat.month.end <-to.period(dat, period='months', indexAt='lastof', OHLC=F)
    
    dat.month.end
                      [,1]
    2000-10-31  1.00117650
    2000-11-30 -1.15090619
    2000-12-31  0.04944459
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 2020-04-18
      • 1970-01-01
      • 2017-10-11
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多