2016-07-26 6 views
1

Ich habe vor kurzem ein Problem in R mit den Daten konfrontiert. Der letzte Tag des Jahres 2015 (2015-12-31) fällt auf Donnerstag, was bedeutet, dass die letzte Woche des Jahres nur 5 Tage umfasst, wenn ich Sonntag als Starttag meiner Woche betrachte. Jetzt möchte ich 2016-01-01 und 2016-01-02, die auf Freitag und Samstag fallen, mit Woche 53 verbunden sein und Woche 1 am 2016-01-03 beginnen, die auf Sonntag fällt.Beginnen Sie den ersten Tag der Woche des Jahres am Sonntag und Ende letzter Tag der Woche des Jahres am Samstag

require(lubridate) 
range <- seq(as.Date('2015-12-26'), by = 1, len = 10) 
df <- data.frame(range) 
df$WKN <- as.numeric(strftime(df$range, format = "%U")) + 1 
df$weekday <- weekdays(df$range) 
df$weeknum <- wday(df$range) 

Dies würde mir folgendes Ergebnis:

df: 
range  WKN weekday weeknum 
2015-12-26 52 Saturday  7 
2015-12-27 53 Sunday  1 
2015-12-28 53 Monday  2 
2015-12-29 53 Tuesday  3 
2015-12-30 53 Wednesday  4 
2015-12-31 53 Thursday  5 
2016-01-01 1 Friday  6 
2016-01-02 1 Saturday  7 
2016-01-03 2 Sunday  1 
2016-01-04 2 Monday  2 

Nun würde Ich mag meinen Datenrahmen haben, wie folgt:

df: 
range  WKN weekday weeknum 
2015-12-26 52 Saturday  7 
2015-12-27 53 Sunday  1 
2015-12-28 53 Monday  2 
2015-12-29 53 Tuesday  3 
2015-12-30 53 Wednesday  4 
2015-12-31 53 Thursday  5 
2016-01-01 53 Friday  6 
2016-01-02 53 Saturday  7 
2016-01-03 1 Sunday  1 
2016-01-04 1 Monday  2 

Könnte mich jemand auf eine Richtung zeigen, dass zu automatisieren damit ich den Code nicht jedes Jahr ändern muss?

Antwort

1

Wenn Sie ?strptime Check-out nutzen können, gibt es ein paar verschiedene Wochennummer Token mit format zur Verfügung. Hier %V fast funktioniert, außer es die Woche am Montag beginnt, so dass man hinzufügen anzupassen:

df$WKN <- as.integer(format(df$range + 1, '%V')) 

df 
##   range WKN weekday weeknum 
## 1 2015-12-26 52 Saturday  7 
## 2 2015-12-27 53 Sunday  1 
## 3 2015-12-28 53 Monday  2 
## 4 2015-12-29 53 Tuesday  3 
## 5 2015-12-30 53 Wednesday  4 
## 6 2015-12-31 53 Thursday  5 
## 7 2016-01-01 53 Friday  6 
## 8 2016-01-02 53 Saturday  7 
## 9 2016-01-03 1 Sunday  1 
## 10 2016-01-04 1 Monday  2 

Oder wenn Sie mit dplyr wie der Tag schon sagt,

library(dplyr) 

df %>% mutate(WKN = as.integer(format(range + 1, '%V'))) 

, die die gleiche Sache zurück . Die isoweek Funktion von lubridate entspricht, so dass Sie auch

library(lubridate) 

df$WKN <- isoweek(df$range + 1) 

oder

df %>% mutate(WKN = isoweek(range + 1)) 

beide die Rückkehr identische Ergebnisse zu den as.integer(format(...)) Versionen tun könnte.

1

Wir cumsum auf einem logischen Vektor

df$WKN <- unique(df$WKN)[cumsum(df$weeknum==1) +1] 
df$WKN 
#[1] 52 53 53 53 53 53 53 53 1 1 
1

In Anbetracht der Tatsache, dass Sie lubridate verwenden, wollte ich Ihnen auch eine Schmiermittellösung geben. Sie haben auch nach einer Lösung gefragt, die mit anderen Jahren funktioniert. Hier geht:

adjust_first_week<- function(year){ 

    first <- floor_date(dmy(paste0("1-1-", year)), "year") 
    two_weeks <- c(first - days(7:1), first + days(0:6)) 

    df <- data.frame(date = two_weeks, 
       day_of_week = weekdays(two_weeks), 
       day_of_year = yday(two_weeks), 
       week_of_year = week(two_weeks)) 

    last_weekend <- which(df$day_of_week == "Sunday")[2] -1 
    df$adjust_week <- df$week_of_year 
    if(last_weekend ==7) return(df) 
    else{ 
     df$adjust_week[8:last_weekend] <- rep(53,length(8:last_weekend)) 
    } 
    return(df) 
    } 
  1. nimmt ein numerisches Jahr und nimmt den ersten Tag des Jahres.
  2. Erstellt einen Zeitraum von zwei Wochen, indem eine Woche auf jeder Seite von 1/1/Jahr angehängt wird.
  3. Berechnet verschiedene zusammenfassende Statistiken für dieses Jahr für Ihre Erbauung.
  4. Ruft den zweiten Sonntag aus. Design 1/1/Jahr ist immer der 8. Eintrag.
  5. Wenn Sonntag der erste Tag des Monats ist, tut es nichts.
  6. Andernfalls überschreibt es die Woche des Jahres, so dass die erste Woche des Jahres am zweiten Sonntag beginnt. Hier

sind die Ergebnisse für

adjust_last_week(2016) 
     date day_of_week day_of_year week_of_year adjust_week 
1 2015-12-25  Friday   359   52   52 
2 2015-12-26 Saturday   360   52   52 
3 2015-12-27  Sunday   361   52   52 
4 2015-12-28  Monday   362   52   52 
5 2015-12-29  Tuesday   363   52   52 
6 2015-12-30 Wednesday   364   52   52 
7 2015-12-31 Thursday   365   53   53 
8 2016-01-01  Friday   1   1   53 
9 2016-01-02 Saturday   2   1   53 
10 2016-01-03  Sunday   3   1   1 
11 2016-01-04  Monday   4   1   1 
12 2016-01-05  Tuesday   5   1   1 
13 2016-01-06 Wednesday   6   1   1 
14 2016-01-07 Thursday   7   1   1 
Verwandte Themen