J’ai mis les données sur Github afin de pouvoir répliquer le notebook facilement.
Le code ci dessous importe la data, formate les variables dates et arrange les variables stock et markingdate par ordre croissant.
library(tidyverse)
## ── Attaching packages ────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.0.0 ✔ purrr 0.3.2
## ✔ tibble 2.1.3 ✔ dplyr 0.8.1
## ✔ tidyr 0.8.3 ✔ stringr 1.3.1
## ✔ readr 1.1.1 ✔ forcats 0.3.0
## ── Conflicts ───────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(lubridate)
##
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
##
## date
nbStart <- dmy('01/01/2018')
nbEnd <- dmy('31/12/2018')
PATH <- "https://raw.githubusercontent.com/thomaspernet/data_csv_r/master/data/CSAV_data.csv"
####
df <- read.csv(PATH, sep = ';') %>%
mutate(MarkingDate = dmy(MarkingDate),
DateDiv = dmy(DateDiv),
PayDate = dmy(PayDate)) %>%
filter(MarkingDate >=nbStart & MarkingDate <=nbEnd) %>%
arrange(Stock, MarkingDate)
head(df)
Ici, on souhaite créer une variable bucket, qui est un index si la MarkingDate
est entre deux dates. Pour cela, on va utiliser la fonction findInterval
.
C’est assez simple, il suffit de créer un vecteur de date qui va spliter la columne MarkingDate
. Par exemple, on souhaite créer un bucket index pour un intervalle tous les trois mois. On créer un vecteur de date:
date_bucket <- c(ymd("2018-03-01"), ymd("2018-06-01"), ymd("2018-09-01"))
Note que j’utilise lubridate
pour créer les dates, cela facilite la manipulation. Ensuite, je vais grouper les MarkingDate selon si elles sont dans les intervalles. Par exemple, si une date est entre le premier intervalle, alors le bucket est 0
, si la date est entre le deuxième intervalle, alors bucket
est égale a 1
et ainsi de suite. Toutes les dates au delà du dernier intervalle vont avoir un index max + 1. Dans notre example, il y a 3 intervalles, toutes les dates au delà du dernier intervalle auront la valeur 3
Attention, il faut que les date soient dans un ordre croissant, c’est pour cela que j’utilise arrange()
Pour pus d’info sur la fonction, ici
date_bucket <- c(ymd("2018-03-01"), ymd("2018-06-01"), ymd("2018-09-01"))
df <- df %>% arrange(MarkingDate) %>%
mutate(bucket = findInterval(MarkingDate,
date_bucket)
)
df
On extrait uniquement les valeurs uniques par groupe
df %>%
group_by(Stock) %>%
select(Stock, MarkingDate) %>%
unique()
on prend seulement le lag
#### No upper/lower bounds
df %>% group_by(Stock) %>%
select(Stock, MarkingDate) %>%
mutate(diff_days = MarkingDate - lag(MarkingDate, 1))
On séléctionne par groupe uniquement la première et dernière date
#### Upper/lower bounds
df %>% group_by(Stock) %>%
select(Stock, MarkingDate) %>%
filter(row_number() %in% c(1, n())) %>%
mutate(diff_days_limits = ifelse(row_number() == 1,
MarkingDate - nbStart,
nbEnd - MarkingDate))
On souhaite avoir les dates non pas en lag mais en forward; Pour aller vers l’avant, on utilise lead
df %>% group_by(Stock) %>%
select(Stock, MarkingDate) %>%
mutate(diff_days =lead(MarkingDate, 4) - MarkingDate)
On séléctionne uniquement les 5 premières valeurs par groupe
df %>% group_by(Stock) %>%
select(Stock, MarkingDate) %>%
filter(row_number() %in% c(seq(1,5))) %>%
mutate(diff_days = MarkingDate - nbStart)
On séléctionne les 4 dernières valeurs par groupe
df %>% group_by(Stock) %>%
select(Stock, MarkingDate) %>%
filter(row_number() %in% c(seq(n() - 3, n()))) %>%
mutate(diff_days = nbEnd- MarkingDate)
Faire les memes KPI que ci-dessus mais cette fois on ne conservant que les marking dates pour lesquelles les valeurs ont bougé (nos fameux carrés).
L’idée est de séléctionner les index des observations qui ont des duplicates ie valeurs identiques. Ensuite, on peut filtrer la data en séléctionnant uniquement les indexes non duplicates
Attention, j’ai crée à la main des valeurs identiques pour faire un test.
PATH2 <- "https://raw.githubusercontent.com/thomaspernet/data_csv_r/master/data/CSAV_data_square.csv"
##### Ci dessous, test avec 2018-01-19 & 2018-01-27 & 2018-08-03 & 2018-08-27 complétements identiques
df_s <- read.csv(PATH2, sep = ';') %>%
mutate(MarkingDate = dmy(MarkingDate),
DateDiv = dmy(DateDiv),
PayDate = dmy(PayDate)) %>%
filter(MarkingDate >=nbStart & MarkingDate <=nbEnd) %>%
arrange(Stock, MarkingDate)
Juste pour info, voici les duplicates
### For the record: the duplicates
df_s %>%
rownames_to_column() %>%
group_by(Stock, DateDiv,Amount,Yield,PayDate) %>%
filter(n() > 1)
Premièrement, on extrait les duplicated indexes
##### Extract index duplicates
index_duplicates <- df_s %>%
rownames_to_column() %>%
group_by(Stock, DateDiv,Amount,Yield,PayDate) %>%
filter(n() > 1) %>%
ungroup()%>%
select(rowname) %>%
mutate(rowname = as.integer(rowname))
index_duplicates$rowname
## [1] 1 2 3 4 5 6 7 8 9 10 15 16 17 18
Ensuite, on filtre la data de base
###### Extract row index of non duplicates
df_s %>%
filter(!row_number() %in% index_duplicates$rowname)