Ok, d'abord un peu de code pour générer des données de test. Cela fait 100 ID aléatoires et pour chacun choisit 20 mois à partir d'une période de 2 ans avec des valeurs aléatoires. La commande est ensuite mélangée pour plus de plaisir.
## Generate some IDs
ids <- sample(1000, 100)
## Generate the data
data <- do.call(rbind,
lapply(ids,
function(id)
data.frame(ID = id,
Date = sample(as.Date(paste(rep(c(2008:2009), each=12),
1:12, 1, sep="-")),
20),
Value = sample(1000, 20))))
## Shuffle
data <- data[sample(nrow(data), nrow(data)),]
est ici à quoi il ressemble pour moi:
> head(data)
ID Date Value
1007 205 2008-07-01 235
1391 840 2008-12-01 509
918 278 2009-12-01 951
1213 945 2009-03-01 842
1369 766 2009-07-01 555
798 662 2008-12-01 531
Ok, maintenant nous allons itérer sur ID et trouvez le diff pour chaque mois pour chaque ID. Avant cela, convertissons le mois en nombre afin qu'il soit plus facile de prendre des différences (c'est un peu sale, est-ce que quelqu'un connaît une meilleure façon de faire de l'arithmétique sur les objets Date?). Cela ne vient year * 12 + month
pour que fonctionne l'arithmétique normale:
data$Month <- as.POSIXlt(data$Date)$mon + as.POSIXlt(data$Date)$year * 12
Maintenant calculer les différences:
by.id <- by(data, data$ID, function(x) {
## Sort by month.
x <- x[order(x$Month),]
## Compute the month and value differences, taking care to pad the edge case.
data.frame(ID=x$ID,
Date = x$Date,
Month.diff=c(0, diff(x$Month)),
Value.diff=c(0,diff(x$Value)))
})
by.id <- do.call(rbind, by.id)
Voici ce que le résultat ressemble à:
> head(by.id)
ID Date Month.diff Value.diff
4.1 4 2008-02-01 0 0
4.2 4 2008-03-01 1 123
4.3 4 2008-05-01 2 -94
4.4 4 2008-06-01 1 -243
4.5 4 2008-08-01 2 -327
4.6 4 2008-10-01 2 656
Si la différence entre les mois consécutifs était supérieur à 1, alors les mois n'étaient pas adjacents et nous devrions mettre leurs valeurs à zéro.
by.id$Value.diff <- ifelse(by.id$Month.diff == 1,
by.id$Value.diff,
0)
Enfin, nous itérer par mois et prendre les différences de N supérieur et inférieur (je vais mettre N à 10 ici au lieu de 100 depuis mon ensemble de données de test est assez faible).
by.month <- by(by.id, by.id$Date, function(x) {
## Sort the data in each month
x <- x[order(x$Value.diff),]
## Take the top and bottom and label them accordingly.
cbind(rbind(head(x, 10), tail(x, 10)),
type=rep(c("min", "max"), each=10))
})
Et là nous l'avons.Voici un résultat exemple:
> by.month[[24]]
ID Date Month.diff Value.diff type
130.20 130 2009-12-01 1 -951 min
415.20 415 2009-12-01 1 -895 min
662.20 662 2009-12-01 1 -878 min
107.20 107 2009-12-01 1 -744 min
824.20 824 2009-12-01 1 -731 min
170.20 170 2009-12-01 1 -719 min
502.20 502 2009-12-01 1 -714 min
247.20 247 2009-12-01 1 -697 min
789.20 789 2009-12-01 1 -667 min
132.20 132 2009-12-01 1 -653 min
64.20 64 2009-12-01 1 622 max
82.20 82 2009-12-01 1 647 max
381.20 381 2009-12-01 1 698 max
303.20 303 2009-12-01 1 700 max
131.20 131 2009-12-01 1 751 max
221.20 221 2009-12-01 1 765 max
833.20 833 2009-12-01 1 791 max
806.20 806 2009-12-01 1 806 max
780.20 780 2009-12-01 1 843 max
912.20 912 2009-12-01 1 929 max
Merci, en cours d'exécution maintenant. L'étape: data <- ddply prend beaucoup de temps, j'espère que cela se terminera bientôt :) Les données d'origine étaient de 50 Mo ou plus, mais il a probablement été considérablement élargi en ajoutant les mois manquants. – rjurney
i ♡ expand.grid –