How to flag last friday or last day or month

前端 未结 4 578
慢半拍i
慢半拍i 2021-01-22 17:53

I have a data frame of dates and the day of the week

> head(data)
         day   weekday
1 2016-01-01    Friday
4 2016-01-04    Monday
5 2016-01-05   Tuesday
         


        
相关标签:
4条回答
  • 2021-01-22 17:56
    require(data.table)
    
    lfom<-function(d){
      x<-seq(min(d),max(d),by=1)
      fri<-which(wday(x)==6)
      mend<-which(mday(x)==1)-1
      d %in%  x[fri[findInterval(mend,fri)]]
    }
    
    ldom<-function(d){
      x<-seq(min(d),max(d),by=1)
      mend<-which(mday(x)==1)-1
      d %in%  x[mend]
    }
    
    
    data <-data.frame(
      day = seq(as.Date("2014-01-01"), as.Date("2016-05-10"), "day"), 
      weekday = weekdays(seq(as.Date("2014-01-01"), as.Date("2016-05-10"), "day"))
    )
    excludeDays <- c("Saturday", "Sunday")
    data <- data.table(subset(data, !weekdays(data$day) %in% excludeDays)) #exclude weekend
    data$lfom<-lfom(data$day)
    data$ldom<-ldom(data$day)
    
    0 讨论(0)
  • 2021-01-22 18:00
    library(lubridate)
    library(dplyr)
    data%>% 
      mutate(year = year(day),month= month(day)) %>%
      group_by(year, month) %>% 
      mutate(LastDayInMonth = max(day)==day)%>% 
      arrange(day) %>%
      ungroup() %>% 
      group_by(year, month, weekday) %>%
      mutate(LastWeekInMonth = row_number() ==  n(), 
             LastFriayInMonth = weekday =="Freitag" & LastWeekInMonth == 1) %>% 
      ungroup()%>%
      select(day, weekday, LastDayInMonth,LastFriayInMonth)
    

    Same excerpt as above (%>% filter(LastDayInMonth | LastFriayInMonth == TRUE):

    Source: local data frame [8 x 4]
    
             day    weekday LastDayInMonth LastFriayInMonth
          (date)     (fctr)          (lgl)            (lgl)
    1 2016-01-29    Freitag           TRUE             TRUE
    2 2016-02-26    Freitag          FALSE             TRUE
    3 2016-02-29     Montag           TRUE            FALSE
    4 2016-03-25    Freitag          FALSE             TRUE
    5 2016-03-31 Donnerstag           TRUE            FALSE
    6 2016-04-29    Freitag           TRUE             TRUE
    7 2016-05-06    Freitag          FALSE             TRUE
    8 2016-05-10   Dienstag           TRUE            FALSE
    
    0 讨论(0)
  • 2021-01-22 18:01

    With the additional clarification and following the comment by @eminik the code below

    library(data.table)
    setDT(data)
    data[, LastDayInMonth := day == max(day), by = .(year(day), month(day))]
    data[, LastFridayInMonth := weekday == "Friday" & day == max(day), 
         by = .(year(day), month(day), weekdays(day))]
    

    produces:

    # show results (only relevant rows)
    data[LastDayInMonth | LastFridayInMonth == TRUE]
    
              day  weekday LastDayInMonth LastFridayInMonth
    1: 2016-01-29   Friday           TRUE              TRUE
    2: 2016-02-26   Friday          FALSE              TRUE
    3: 2016-02-29   Monday           TRUE             FALSE
    4: 2016-03-25   Friday          FALSE              TRUE
    5: 2016-03-31 Thursday           TRUE             FALSE
    6: 2016-04-29   Friday           TRUE              TRUE
    7: 2016-05-06   Friday          FALSE              TRUE
    8: 2016-05-10  Tuesday           TRUE             FALSE
    

    Edit: Code modified to account for change of years as requested by OP.

    Note: weekdays returns a character vector of names in the locale in use. Therefore, the code only works if you are in an English locale. Otherwise, you may have to use Sys.setlocale(category = "LC_ALL", locale = "English") before.

    0 讨论(0)
  • 2021-01-22 18:03

    I'm using lubridate for date calculations, but since you have missing days in between, I use lead() function from dplyr to find the next day (row) in the data.

    library(lubridate)
    library(dplyr)
    my.data <- tbl_df(data)
    my.data <- my.data %>% 
        # First last day of month
        # get the next day in the data
        mutate(next.day = lead(day)) %>%
        # it's month is different
        mutate(LastDayInMonth = ifelse(month(day) != month(next.day), T, F)) %>%
        # Now Last Friday
        mutate(LastFridayInMonth = 
                   ifelse( (wday(day) == 6) & # It's a Friday
                    # Check the month of next Friday, different
                    (month(lead(day, 5)) != month(day)
                     | is.na(lead(day, 5))), T, F))
    
    0 讨论(0)
提交回复
热议问题