我的数据框有4000多列和3000行。列是公司,行有每日股票收盘价。行具有基于月份日期的每日观察数据。现在,我想要删除每个月的最后一个日期之间的行,即我希望根据我的数据框中的月份的可用日期来获得仅一个月的最后一天的数据。每个月的最后日期应该根据我的数据框中的日期列。 我的问题与其他人的主要挑战和区别是上个月的日期应该根据我的数据框中提供的日期。它是一个财务数据和非交易日,没有。交易日与其他类型的行业不同 我举例说明了我的数据框的一部分。
Date A B
30/12/1999 1 3
04/01/2000 1 3
05/01/2000 1 3
06/01/2000 1 3
07/01/2000 1 3
10/01/2000 1 3
11/01/2000 1 3
12/01/2000 1 3
13/01/2000 1 3
14/01/2000 1 3
17/01/2000 1 3
18/01/2000 1 3
19/01/2000 1 3
20/01/2000 1 3
21/01/2000 1 3
24/01/2000 1 3
25/01/2000 1 3
26/01/2000 1 3
27/01/2000 1 3
28/01/2000 1 3
31/01/2000 1 3
01/02/2000 1 3
02/02/2000 1 3
03/02/2000 1 3
04/02/2000 1 3
07/02/2000 1 3
08/02/2000 1 3
09/02/2000 1 3
10/02/2000 1 3
11/02/2000 1 3
14/02/2000 1 3
15/02/2000 1 3
16/02/2000 1 3
17/02/2000 1 3
18/02/2000 1 3
21/02/2000 1 3
22/02/2000 1 3
23/02/2000 1 3
24/02/2000 1 3
25/02/2000 1 3
28/02/2000 1 3
29/02/2000 1 3
期望的输出
Date A B
30/12/1999 1 3
31/01/2000 1 3
29/02/2000 1 3
我非常感谢你在这方面的帮助。
答案 0 :(得分:4)
使用lubridate
和dplyr
,先解析Date
library(lubridate)
library(dplyr)
df$Date <- dmy(df$Date)
现在我们可以构建一个dplyr
链来过滤:
df %>% group_by(month = month(Date), year = year(Date)) %>% filter(Date == max(Date))
我们添加了group_by
month
和year
列,然后filter
向下只显示每个组的max
日期。它返回
Source: local data frame [3 x 5]
Groups: month, year [3]
Date A B month year
(time) (int) (int) (dbl) (dbl)
1 1999-12-30 1 3 12 1999
2 2000-01-31 1 3 1 2000
3 2000-02-29 1 3 2 2000
如果您愿意的话,当然可以在基地R中完成所有这些。
修改:H / T @Jaap建议使用group_by
添加列而不是单独的mutate
。您也可以使用slice(which.max(Date))
代替filter
字词;如果这是一个问题,它可能会更快提示。
答案 1 :(得分:2)
我们也可以使用data.table
library(data.table)
library(lubridate)
setDT(df1)[, c('month', 'year', 'Date') :={tmp <- dmy(Date)
list(month= month(tmp), year= year(tmp), Date= tmp)}
][, .SD[ which.max(Date)] ,.(month, year)]
# month year Date A B
#1: 12 1999 1999-12-30 1 3
#2: 1 2000 2000-01-31 1 3
#3: 2 2000 2000-02-29 1 3
答案 2 :(得分:2)
这是另一种可能性:
month_year <- as.numeric(as.factor(sub("^[0-9]*/","",df1$Date)))
df1[!!c(diff(month_year),1),]
# Date A B
#1 30/12/1999 1 3
#21 31/01/2000 1 3
#42 29/02/2000 1 3
此解决方案不会更改原始数据框中日期的格式。但是,假设数据按时间顺序排列,就像OP中显示的数据一样。
数据强>
df1 <- structure(list(Date = structure(c(41L, 4L, 6L, 7L, 8L, 12L, 14L,
16L, 17L, 18L, 22L, 24L, 26L, 27L, 28L, 32L, 34L, 36L, 37L, 38L,
42L, 1L, 2L, 3L, 5L, 9L, 10L, 11L, 13L, 15L, 19L, 20L, 21L, 23L,
25L, 29L, 30L, 31L, 33L, 35L, 39L, 40L), .Label = c("01/02/2000",
"02/02/2000", "03/02/2000", "04/01/2000", "04/02/2000", "05/01/2000",
"06/01/2000", "07/01/2000", "07/02/2000", "08/02/2000", "09/02/2000",
"10/01/2000", "10/02/2000", "11/01/2000", "11/02/2000", "12/01/2000",
"13/01/2000", "14/01/2000", "14/02/2000", "15/02/2000", "16/02/2000",
"17/01/2000", "17/02/2000", "18/01/2000", "18/02/2000", "19/01/2000",
"20/01/2000", "21/01/2000", "21/02/2000", "22/02/2000", "23/02/2000",
"24/01/2000", "24/02/2000", "25/01/2000", "25/02/2000", "26/01/2000",
"27/01/2000", "28/01/2000", "28/02/2000", "29/02/2000", "30/12/1999",
"31/01/2000"), class = "factor"), A = c(1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L), B = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L
)), .Names = c("Date", "A", "B"), class = "data.frame", row.names = c(NA,
-42L))
答案 3 :(得分:1)
我会创建一个包含数据结束日期的向量,如下所示:
library(dplyr)
df.dates = seq(as.Date("1999-01-01"),as.Date(Sys.Date()),by="months")-1
df.dates = as.data.frame(df.dates)
names(df.dates) = "Date"
df.joined = inner_join(df.dates, df)
这假设您将数据放在数据框中,并将Date列命名为“Date”
*重新阅读问题,如果最后一个交易日不是该月的最后一天,这将无效。 @alistaire使用max(Date)
有更好的解决方案