6
votes

Comment convertir la date en week-end le plus proche (samedi)

J'ai un bloc de données avec la date au format «% d-% m-% Y» et j'ai le numéro de la semaine. Les dates sont des jours de la semaine et je veux le samedi de cette semaine dans une autre colonne.

J'ai d'abord vérifié si la date est un jour de semaine ou un week-end en utilisant la fonction dans le package Chron, mais c'était une validation booléenne. J'avais formaté la variable de date au format Date et extrait le numéro de semaine pour chaque date.

date        week    EOW  
2014-08-20   34   2014-08-23

2014-08-25   34   2014-08-30

2014-10-08   41   2014-10-11

Le résultat attendu devrait être:

df = data.frame(date=c("2014-08-20", "2014-08-25", "2014-10-08")) 
df$date=as.Date(df$date,format="%Y-%m-%d")
df$week=week(ymd(df$date))


0 commentaires

3 Réponses :


5
votes

Option de base R. Créez d'abord une liste de tous les jours, puis faites correspondre avec jours de la semaine et soustrayez-la de 6 (comme nous voulons samedi) pour obtenir le nombre de jours que nous devons ajouter à l'original Colonne date .

library(lubridate)
df$EOW <- ceiling_date(df$date, unit = "week") - 1

Ou lubridate a une fonction plafond_date qui, lorsqu'elle est utilisée avec unit = "week" vous renverrait le prochain "dimanche" donc nous en soustrayons 1 jour pour obtenir "samedi" à la place.

all_days <- c("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday")

#As @nicola mentioned this is locale dependent
#If your locale is not English you need weekdays in your current locale
#which you can manually write as shown above or do any one of the following

#all_days <- weekdays(seq(as.Date("2019-01-14"),by="day",length.out=7))
#OR
#all_days <- format(seq(as.Date("2019-01-14"),by="day",length.out=7), "%A")

df$EOW <- df$date + 6 - match(weekdays(df$date), all_days)

df
#        date week        EOW
#1 2014-08-20   34 2014-08-23
#2 2014-08-25   34 2014-08-30
#3 2014-10-08   41 2014-10-11


0 commentaires

1
votes

Une autre façon d'utiliser

library(data.table)
df <- data.table(date=c("2014-08-20", "2014-08-25", "2014-10-08")) 
df$date=as.Date(df$date,format="%Y-%m-%d")
df$week=week(ymd(df$date))

## if the locale is not English, please use the local values for days 
days <- data.frame(DOW = c("Monday", "Tuesday", "Wednesday", "Thursday","Friday", "Saturday", "Sunday"))
days$day <- seq(1,7,1)

df <- df[,DOW:= weekdays(date)]
df <- merge(df, days, all.x = T, by = "DOW")

df <- df[, EOW := date + (6 - day)]
df

         DOW       date week day        EOW
1:    Monday 2014-08-25   34   1 2014-08-30
2: Wednesday 2014-08-20   34   3 2014-08-23
3: Wednesday 2014-10-08   41   3 2014-10-11


1 commentaires

Quant à l'autre réponse, cette solution dépend des paramètres régionaux. Voir mon commentaire ici.



0
votes

Jouer avec la syntaxe de jointure data.table :

library(data.table)

# Create a saturdays dataset
saturdays2014 <- data.table(date = seq(as.Date("2014-01-01"), as.Date("2014-12-31"), by = 1))
Sys.setlocale("LC_ALL","English")
saturdays2014 <- saturdays2014[weekdays(date) == "Saturday"]

# convert df to data.table and date to a Date variable
setDT(df)[, date := as.Date(date)]

# Join
df[saturdays2014, on = "date", roll = 6, EOW := i.date]
df    
#          date        EOW
# 1: 2014-08-20 2014-08-23
# 2: 2014-08-25 2014-08-30
# 3: 2014-10-08 2014-10-11


1 commentaires

Aussi dépendant localement, mais devrait suffire au filtrage pour connaître une date qui est un samedi et à partir de là utiliser le fait qu'ils se produisent tous les 7 jours.