#r #date #product
#r #Дата #продукт
Вопрос:
Я очень новичок в форуме, и я надеюсь, что вопрос понятен.
У меня есть фрейм данных (df) следующим образом
id date announcement_date ret
12055 2001-08-02 2001-08-03 1.0246
12055 2001-08-03 2001-08-03 1.123
12055 2001-08-04 2001-08-03 0.994
11033 2001-08-02 2001-08-05 1.020
11033 2001-08-03 2001-08-05 0.997
11033 2001-08-04 2001-08-05 0.949
11033 2001-08-05 2001-08-05 1.048
11033 2001-08-06 2001-08-05 1.060
11033 2001-08-07 2001-08-05 1.002
Как я могу создать новый столбец, который включает в себя произведение ‘ret’, сгруппированное по идентификатору от announcement_date до последнего существующего дня? То есть для id = 11033 я бы хотел создать новый столбец «Продукт», который выглядит так:
id date announcement_date ret Product
11033 2001-08-02 2001-08-05 1.020 -
11033 2001-08-03 2001-08-05 0.997 -
11033 2001-08-04 2001-08-05 0.949 -
11033 2001-08-05 2001-08-05 1.048 1.048
11033 2001-08-06 2001-08-05 1.060 1.048*1.060
11033 2001-08-07 2001-08-05 1.002 1.048*1.060*1.002
Я попробовал код
df$product <- aggregate(ret ~ id ret, df, prod)
Это работает, но я получаю произведение ‘ret’ для каждого ‘id’ по всем датам, т.Е. Я не знаю, как установить для ‘начальной даты’ значение announcement_date.
Ответ №1:
Работает ли это:
library(purrr)
library(dplyr)
df %>% group_by(id) %>% filter(date>=announcement_date) %>%
mutate(Product = accumulate(ret, `*`)) %>% as.data.frame() %>% right_join(df) %>%
arrange(desc(id), date)
Joining, by = c("id", "date", "announcement_date", "ret")
id date announcement_date ret Product
1 12055 2001-08-02 2001-08-03 1.0246 NA
2 12055 2001-08-03 2001-08-03 1.1230 1.123000
3 12055 2001-08-04 2001-08-03 0.9940 1.116262
4 11033 2001-08-02 2001-08-05 1.0200 NA
5 11033 2001-08-03 2001-08-05 0.9970 NA
6 11033 2001-08-04 2001-08-05 0.9490 NA
7 11033 2001-08-05 2001-08-05 1.0480 1.048000
8 11033 2001-08-06 2001-08-05 1.0600 1.110880
9 11033 2001-08-07 2001-08-05 1.0020 1.113102
Комментарии:
1. Спасибо! Это прекрасно работает. Как бы вы построили диапазон дат? Я попробовал фильтр (дата>=announcement_date, дата <=announcement_date 45). Однако каким-то образом код игнорирует верхнюю границу.
2. @hyun_12055, вы можете использовать функцию between: between(дата, announcement_date, announcement_date <=45)
3. @hyun_12055, если мой ответ сработал, не могли бы вы принять его, нажав на галочку рядом с моим ответом.