Calculer le nombre de semaines (0-53) dans l'année

j'ai un ensemble de données avec des localisations et des dates. Je voudrais calculer la semaine de l'année comme nombre (00-53), mais en utilisant le jeudi comme premier jour de la semaine. Les données ressemble à ceci:

  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

je sais qu'il y a la fonction strftime pour calculer la semaine de l'année mais il est seulement possible d'utiliser le lundi ou le dimanche comme premier jour de la semaine. Toute aide serait très appréciée.

14
demandé sur Jaap 2013-03-07 21:45:53

2 réponses

il suffit d'ajouter 4 aux valeurs formatées par Date:

> 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

cela utilise une convention de comptage basée sur 0 puisque c'est ce que strftime fournit et nous sommes juste en train de pigbacker cette base de code, donc le premier vendredi d'une année qui commence le mardi comme ce fut le cas en 2013 serait un résultat d'une semaine. Ajoutez 1 à la valeur si vous voulez une convention basée sur 1. (Fondamentalement, les valeurs datées sont dans une séquence entière de "l'origine" de sorte qu'elles ne reconnaissent pas vraiment les années ou les semaines. Ajout de 4 change juste le cadre de référence de la Date sous-jacente-entier.)

Note D'édition. Transformé en ajouter trois stratégie par Gabor conseils. .... ce qui ne répond toujours pas à la question de savoir comment traiter la dernière semaine de l'année précédente.

22
répondu 42- 2013-03-07 21:20:47

puisque la question indique que la semaine va de 00 à 53, nous supposons que le nombre de semaines est le nombre de jeudis de l'année au plus tard à la date en question. Ainsi, le premier jeudi de l'année commence la semaine 1 et la semaine 0 est attribuée aux jours antérieurs.

(il y a eu des commentaires selon lesquels si le premier jour de l'année était le mardi, ce serait la semaine 1, mais si tel était le cas, il ne pourrait jamais y avoir une semaine 0 comme cela semble être exigé dans le sujet, de sorte que certains il pourrait être nécessaire de clarifier la définition précise du nombre de semaines. Ici, nous allons utiliser la définition du paragraphe précédent, mais il ne serait pas difficile de la changer si nous connaissions la définition. Par exemple, si nous avons toujours voulu que la première semaine de l'année soit 1, même si c'était une semaine courte, nous pourrions ajouter !is.thu(jan1(d)) pour le résultat.)

les deux solutions ci-dessous sont suffisamment courtes pour qu'elles puissent être exprimées en une seule déclaration; cependant, nous avons les a pondérés en plusieurs fonctions courtes chacune pour la clarté. La première est particulièrement simple mais la seconde est automatiquement vectorisée sans avoir besoin d'un sapply et serait probablement plus efficace.

1. somme jeudis dans l'année Cette solution suppose l'entrée d est de classe "Date" et résume simplement le nombre de jeudis dans l'année, avant ou sur:

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"))))
}

Nous pouvons tester ceci:

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

basé sur le nextfri fonction dans le zoo quickref vignette nous voyons que le nombre de jours depuis l'Époque (1970-01-01) de jeudi prochain (ou le jour en question si sa déjà un jeudi) est donnée par nextthu dans la première ligne ci-dessous. L'application au premier jour de l'an nous tirons le résultat où d est comme avant:

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

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

et voici un test

week4a(d) # 1 4 5 6 7 9

ajouté: correction d'un bug dans la deuxième solution.

2
répondu G. Grothendieck 2013-03-07 22:01:31