我有一个数据帧z,我每天有800万观察。对于每个公司(用seriesid衡量)我想要月份中的最后一个值(如果可用),以及总回收和收盘价之前(月内)的值。
我尝试过使用z[apply.monthly(z$date,max,by = z$seriesid)]
,但这只返回NAs。使用apply的其他尝试只返回一个日期值(因此不与seriesids结合)
date company totalreturn close seriesid
1: 2018-01-30 x 910.2214 133.375 55860
2: 2018-02-06 x 905.9561 132.750 55860
3: 2018-02-13 x 900.8377 132.000 55860
4: 2018-02-20 x 900.8377 132.000 55860
5: 2018-02-27 x 911.0745 133.500 55860
6: 2017-03-06 y 921.3112 135.000 55940
7: 2017-03-13 y 917.8990 134.500 55940
理想情况下,数据集将显示为
date company totalreturn close seriesid
1: 2018-01-30 x 910.2214 133.375 55860
5: 2018-02-27 x 911.0745 133.500 55860
7: 2017-03-13 y 917.8990 134.500 55940
每个公司每月包含一个不是NA的观察
使用dplyr
和lubridate
的一个解决方案可能是:
df %>%
mutate(date = ymd(date)) %>%
na.omit() %>%
group_by(seriesid, year_month = paste(year(date), month(date), sep = "_")) %>%
filter(date == max(date)) %>%
ungroup() %>%
select(-year_month)
date company totalreturn close seriesid
<date> <chr> <dbl> <dbl> <int>
1 2018-01-30 x 910. 133. 55860
2 2018-02-27 x 911. 134. 55860
3 2017-03-13 y 918. 134. 55940
或者只是dplyr
:
df %>%
mutate(date = as.Date(date, format = "%Y-%m-%d")) %>%
na.omit() %>%
group_by(seriesid, year_month = format(date, "%Y-%m")) %>%
filter(date == max(date)) %>%
ungroup() %>%
select(-year_month)
首先,它删除NA行。其次,它按“seriesid”和年和月的组合分组。最后,它保留每年和每月最大日期和“系列”的行。
我们可以group_by
seriesid
和年月,并选择totalreturn
和close
的非NA的最后一行。
library(dplyr)
df %>%
group_by(seriesid, month = format(date, "%Y%m")) %>%
slice(which.max(cumsum(!is.na(totalreturn) & !is.na(close)))) %>%
ungroup() %>%
select(-month)
# date company totalreturn close seriesid
# <date> <fct> <dbl> <dbl> <int>
#1 2018-01-30 x 910. 133. 55860
#2 2018-02-27 x 911. 134. 55860
#3 2017-03-13 y 918. 134. 55940
这假设您的date
列是Date类型,否则您需要先将其更改为Date类。
或者使用基地R ave
我们可以做到
df1 <- df[complete.cases(df), ]
df1[unique(with(df1, ave(seq_along(date), seriesid, format(date, "%Y%m"),
FUN = function(x) tail(x, 1)))), ]