2013-03-07 13 views
14

Mam zestaw danych z lokalizacjami i datami. Chciałbym obliczyć tydzień roku jako liczbę (00-53), ale używając czwartku jako pierwszego dnia tygodnia. Dane wygląda następująco:Oblicz numer tygodnia (0-53) w roku

location <- c(a,b,a,b,a,b) 
    date <- c("04-01-2013","26-01-2013","03-02-2013","09-02-2013","20-02-2013","03-03-2013") 
    mydf <- data.frame(location, date) 
    mydf 

wiem, że tam jest strftime funkcja obliczania tydzień roku, ale to jest tylko możliwe użycie poniedziałek lub niedzielę jako pierwszy dzień tygodnia. Każda pomoc będzie bardzo ceniona.

+0

Dlaczego chcesz to zrobić, jeśli mogę zapytać? – Arun

+3

Więc jeśli rok rozpoczął się we wtorek, tydzień 1 to wt/środa, a tydzień 2 zaczyna się w czwartek ...? – joran

+0

tak. Tydzień powinien być od wt. Do śr. – Eco06

Odpowiedz

22

Wystarczy dodać 4 do wartości data w formacie:

> mydf$Dt <- as.Date(mydf$date, format="%d-%m-%Y") 
> weeknum <- as.numeric(format(mydf$Dt+3, "%U")) 
> weeknum 
[1] 1 4 5 6 7 9 

ta wykorzystuje 0 na podstawie konwencji liczenia, ponieważ to właśnie strftime zapewnia i jesteśmy po prostu piggybacking off tej podstawy kodu, więc pierwszy piątek w sposób Rok rozpoczynający się we wtorek, tak jak miało to miejsce w 2013 r., byłby wynikiem 1 tygodnia. Dodaj 1 do wartości, jeśli chcesz mieć jedną konwencję. (Zasadniczo, wartości sformatowane w datach są w sekwencji całkowitoliczbowej od "początku", więc tak naprawdę nie rozpoznają lat lub tygodni. Dodanie 4 tylko przesuwa ramkę odniesienia podstawowej liczby całkowitej.)

Edytuj notatkę. Zmieniono na dodanie trzech strategii zgodnie z radą Gabora. .... które wciąż nie rozwiązuje kwestii jak radzić sobie z ostatnim tygodniem ubiegłego roku.

+1

Istnieje pewne pytanie, na czym polega definicja liczby tygodniowej, ale w każdym przypadku są odpowiednio 1, 4, 5, 6, 7, 9 czwartki w roku poprzedzającym 6 dat w pytaniu, co rodzi pytanie, czy 8 w odpowiedzi jest poprawne. Również 'format (as.Date (" 2013-12-31 ") + 4,"% U ")' daje 00. –

+0

Strategia "add-4" tworzy inkrement w czwartek, więc liczba czwartków byłaby zgodna ze strategią "add-3". –

+0

Rozwiązaniem problemu z końca roku może być odjęcie 7 dni, jeśli jest to w grudniu, a następnie dodanie 1 do liczby tygodni: 'ifelse (miesiące (d) ==" grudzień ", \t as.numeric (format (d-4, "% U")) + 1, \t as.numeric (format (d + 3, "% U"))) ' –

2

Ponieważ pytanie, które dotyczy tygodnia od 00-53, przyjmujemy, że liczba tygodni to liczba czwartków w danym roku w danym dniu lub przed tą datą. Tak więc pierwszy czwartek roku rozpoczyna się w pierwszym tygodniu, a tydzień 0 jest przypisany do dowolnych dni wcześniej.

(Pojawiły się uwagi, że jeśli pierwszy dzień roku byłby we wtorek, to byłby tydzień 1, ale gdyby tak było, nigdy nie byłoby tygodnia 0, co wydaje się wymagane w temacie, więc pewne wyjaśnienia dotyczące jaka może być wymagana definicja liczby tygodniowej, tutaj użyjemy definicji z poprzedniego paragrafu, ale nietrudno byłoby ją zmienić, gdybyśmy wiedzieli, jaka jest definicja, na przykład, jeśli zawsze chcieliśmy tego pierwszego tygodnia w roku 1, nawet jeśli był to krótki tydzień, możemy dodać !is.thu(jan1(d)) do wyniku.)

Oba poniższe rozwiązania są na tyle krótkie, że można je wyrazić jednym zdaniem; jednak, dla jasności, umieściliśmy je w kilku krótkich funkcjach. Pierwsza jest szczególnie prosta, ale druga jest automatycznie wektoryzowana bez potrzeby stosowania sapply i prawdopodobnie byłaby bardziej wydajna.

1. suma czwartki w roku To rozwiązanie zakłada wejście d jest klasy "Date" i po prostu sumuje liczbę czwartki w roku przed lub na nim:

is.thu <- function(x) weekdays(x) == "Thursday" 
jan1 <- function(x) as.Date(cut(x, "year")) 

week4 <- function(d) { 
    sapply(d, function(d) sum(is.thu(seq(jan1(d), d, by = "day")))) 
} 

Możemy przetestować go w ten sposób :

d <- as.Date(c("2013-01-04", "2013-01-26", "2013-02-03", "2013-02-09", 
    "2013-02-20", "2013-03-03")) 
week4(d) # 1 4 5 6 7 9 

2. nextthu

Na podstawie funkcji nextfri w zoo quickref vignette widzimy, że liczba dni od Epoki (1970-01-01) następnego czwartku (lub danego dnia, jeśli jest już czwartek) jest taka, jak podana przez nextthu w pierwszym linia poniżej.Stosując to do pierwszego dnia roku czerpiemy wynik gdzie d jest jak dawniej:

nextthu <- function(d) 7 * ceiling(as.numeric(d)/7) 

week4a <- function(d) (as.numeric(d) - nextthu(jan1(d))) %/% 7 + 1 

A oto test

week4a(d) # 1 4 5 6 7 9 

Dodano: poprawiony błąd w drugim roztworze.

Powiązane problemy