calcul de variation au cours du temps

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Coralie Deniot
Messages : 20
Enregistré le : 04 Nov 2015, 08:09

calcul de variation au cours du temps

Messagepar Coralie Deniot » 28 Juin 2017, 07:55

Bonjour à tous !
Cela fait bien longtemps que ne suis pas revenu poser de question. Je remercierais tous ceux qui m'apporteront leur aide :)

J'ai deux questions qui se suivent et portent sur le même tableau de données.

DESCRIPTION DU JEU DE DONNEES:
3 colonnes
-Date et heure de la journée concernée: il y a un relevé environ toutes les 10minutes voir 40 minutes pendant 365 jours
-Poids: Pour chaque relevé de donné, on relève le poids
-Température: Pour chaque relevé de donné, on relève la température
NB: le tableau de donnée fait 20 000 lignes * 40 individus ==> beaucoup de lignes donc ! :)
(Voir un modèle du tableau de donné dans le code ci dessous)

QUESTION 1 : CALCULER LA VARIATION DE POIDS, DE TEMPERATURE ET DE TEMPS EN MINUTE AU COURS DU TEMPS
Je souhaite calculer la variation de poids et de température au cours du temps, en partant d'un poids et d'une température initiale de zéro. Le relevé qui suit sera donc par exemple : "+0.5Kg" et "+1°C" en "10 min". Ces variations calculées s'ajouteraient dans de nouvelles colonnes.
NB: On peut avoir des variations négatives ou positives bien sûr.
(Voir un modèle du tableau final souhaité dans le code ci dessous)

QUESTION 2 : SOMMER LES VARIATION PAR PAS DE 30 MINUTES
Une fois obtenu le nouveau tableau avec les variation, j'aimerais le transformer. Il me faut sommer les variations ayant lieux dans les 30 minutes. Autrement dit, j'aimerais calculer les variations de poids et température toutes les 30 minutes. Le relevé des données n'étant pas toujours régulier dans le temps, je dois le réajuster par cette manipulation.
NB1: Si la variation de temps est déjà supérieure à 30 min on ne fait pas de somme et on laisse la ligne telle quelle
NB2: Si la somme des variations de temps n'est pas pile égale à 30 min, on peut autoriser une fourchette de 30min +/- 10min
NB3: Des lignes allant être supprimer en sommant, on gardera la "date heure" de la borne supérieure
(Voir un modèle du tableau final souhaité dans le code ci dessous)


Code : Tout sélectionner

#DESCRIPTION DU JEU DE DONNEES
date.heure <- c("01/01/2017 8:00:00","01/01/2017 8:10:00","01/01/2017 8:25:00","01/01/2017 8:30:00", "01/01/2017 9:10:00")
poids <- c(20,20.5,22,21,30)
temperature <- c(15,16,20,18,26)
tab <- cbind(date.heure, poids, temperature)
tab

#QUESTION 1 : CALCULER LA VARIATION DE POIDS DE TEMPERATURE ET DE TEMPS EN MINUTE AU COURS DU TEMPS
v.minute <- c(0,10,15,5,40) 
v.poids <- c(0,0.5,1.5,-1,9)
v.temperature <- c(0,1,4,-2,8)
tab <- cbind(tab,v.minute, v.poids, v.temperature)
tab

#QUESTION 2 : SOMMER LES VARIATION PAR PAS DE 30 MINUTES
date.temps.30min <- c("01/01/2017 8:30:00", "01/01/2017 9:10:00") #On prend la date en borne supérieure
somme.minute <- c(0+10+15+5, 40)
somme.poids <- c(0+0.5+1.5-1, 9)
somme.temperature <- c(0+1+4-2, 8)
tab.30minute <- cbind(date.temps.30min, somme.minute, somme.poids, somme.temperature)
tab.30minute


Merci beaucoup pour votre aide, je sais que la deuxième partie de la question est un peu pointilleuse et peut être difficilement réalisable mais si vous avez des propositions autres qui se rapproche de mon objectif je suis ouverte :)

Très bonne journée à vous!

Coralie

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: calcul de variation au cours du temps

Messagepar Logez Maxime » 28 Juin 2017, 12:39

Bonjour,

pour la première partie :

Code : Tout sélectionner

date.heure <- as.POSIXct(date.heure, format = "%d/%m/%Y %H:%M:%S")
tab <- data.frame(date.heure = date.heure, poids = poids, temperature = temperature)
res <- rbind(0,sapply(lapply(tab, diff), as.numeric))
colnames(res) <- sprintf("v.%s", c("minute", "poids", "temperature"))
res <- cbind(tab, res)
res
           date.heure poids temperature v.minute v.poids v.temperature
1 2017-01-01 08:00:00  20.0          15        0     0.0             0
2 2017-01-01 08:10:00  20.5          16       10     0.5             1
3 2017-01-01 08:25:00  22.0          20       15     1.5             4
4 2017-01-01 08:30:00  21.0          18        5    -1.0            -2
5 2017-01-01 09:10:00  30.0          26       40     9.0             8
Cordialement,
Maxime

Coralie Deniot
Messages : 20
Enregistré le : 04 Nov 2015, 08:09

Re: calcul de variation au cours du temps

Messagepar Coralie Deniot » 28 Juin 2017, 14:01

Bonjour Maxime,

Je comprends ton script. Tout réside dans la fonction diff dans le lapply. J'avais essayé la fonction diff mais sans succès car il devait me manquer le as.numeric.

Du coup je te remercie très sincèrement pour ton aide Maxime, c'est gentil d'avoir pris le temps ! Bonne journée :)

Coralie

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: calcul de variation au cours du temps

Messagepar Pierre-Yves Berrard » 07 Juil 2017, 09:26

Coralie Deniot a écrit :QUESTION 2 : SOMMER LES VARIATION PAR PAS DE 30 MINUTES
Une fois obtenu le nouveau tableau avec les variation, j'aimerais le transformer. Il me faut sommer les variations ayant lieux dans les 30 minutes. Autrement dit, j'aimerais calculer les variations de poids et température toutes les 30 minutes. Le relevé des données n'étant pas toujours régulier dans le temps, je dois le réajuster par cette manipulation.
NB1: Si la variation de temps est déjà supérieure à 30 min on ne fait pas de somme et on laisse la ligne telle quelle
NB2: Si la somme des variations de temps n'est pas pile égale à 30 min, on peut autoriser une fourchette de 30min +/- 10min
NB3: Des lignes allant être supprimer en sommant, on gardera la "date heure" de la borne supérieure
(Voir un modèle du tableau final souhaité dans le code ci dessous)

Bonjour,

Un problème si bien présenté mérite qu'on se penche dessus !

Il me semble que les règles NB1 et NB2 ne prennent pas en compte tous les cas possibles.
Par exemple, que faire pour deux temps successifs de 29 min, puis 12 min ?
PY

Coralie Deniot
Messages : 20
Enregistré le : 04 Nov 2015, 08:09

Re: calcul de variation au cours du temps

Messagepar Coralie Deniot » 07 Juil 2017, 20:57

Bonjour Pierre Yves,
Merci pour ton compliments c'est très gentil. J'ai travaillé avec des statistiens qui m'ont appris à bien poser les questions. Car souvent à réponse vient en réfléchissant bien à la question.
Sinon, pour te répondre:
-Environ 80% de mes données ont une variation de temps compris entre 10 et 12 minutes.
-Du coup je pense supprimer toutes les lignes qui ont pas une variation temps supérieure à 30min. Je ne perdrais pas trop de données et ça sera plus facile pour gérer les données.
- Ainsi ma nouvelle question est d'abord: comment supprimer toutes les lignes où la variation de temps est supérieure à 30min (je me doute que cela n'est pas trop difficile mais je n'ai juste pas encore eu le temps de me pencher dessus :) )
-une fois cela fait, je n'aurai plus que des lignes de variations de temps comprise entre 0 et 30min. Ainsi je souhaite Sommer les pas de temps pour que le pas de temps soit minimum de 30min et maximun de 1h.
Ainsi un pas de temps de 29min serait sommé avec le pas de temps suivant de 12min selon ton exemple :)
On aurait donc un pas de temps de 41 min. Ce qui est correct car on est supérieur à 30min et inférieur à 1h.

Merci beaucoup pour ton aide et ta volonté. J'espère que la réponse n'est pas trop décevante (pour un samedi soir en weekend ^^) mais en tout cas n'hésite pas! C'est vrai que normalement le weekend je mes le boulot sur pause mais quand j'ai la chance d'avoir des gens qui veulent m'aider je ne peux pas refuser ! C'est tellement gentil de votre part !

Très bonne soirée à vous ! N'hésitez surtout pas si vous avez d'autres interrogations si ce n'est pas clair .

Très bon weekend !

Coralie

Coralie Deniot
Messages : 20
Enregistré le : 04 Nov 2015, 08:09

Re: calcul de variation au cours du temps

Messagepar Coralie Deniot » 10 Juil 2017, 13:28

Je vois que malgré mon explication je n'ai pas de retour ... N'hésitez surtout pas si ce n'est pas clair!
En gros j'aimerais avoir un pas de temps le plus proche de la 1/2h en restant inférieur à 1h et supérieur à 10min.
J'ai pensé à la fonction "cumsum" sous condition mais je n'arrive pas à savoir comment l'utiliser exactement ...

Encore merci pour votre aide ce qui auront le courage! :)

Coralie

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: calcul de variation au cours du temps

Messagepar Pierre-Yves Berrard » 10 Juil 2017, 15:20

Bonjour,

Si, c'est plus clair, j'y ai réfléchi un peu sans trouver (pour l'instant) une solution parfaite.

Mon idée serait d'attribuer un même groupe aux lignes devant être sommées. Cette partie là qui plus difficile, car le groupe dépend des valeurs précédentes et on ne peut pas "vectoriser" l'opération (avec cumsum, par exemple) comme on aime le faire en R.
(je pense au passage qu'il faudrait garder les valeurs supérieures à 30, car elles serviront à délimiter les frontières des autres groupes)

Une fois les groupes déterminés, c'est assez immédiat avec le package dplyr par exemple.

Code : Tout sélectionner

library(dplyr)
data %>%
  group_by(groupe) %>%
  summarize(
    v.minute_total = sum(v.minute),
    v.poids_total = sum(v.poids),
    v.temperature_total = sum(v.temperature),
    date.heure = last(date.heure)
  )
PY

Coralie Deniot
Messages : 20
Enregistré le : 04 Nov 2015, 08:09

Re: calcul de variation au cours du temps

Messagepar Coralie Deniot » 11 Juil 2017, 07:18

Bonjour Pierre-Yves,

C'est un plaisir de voir que quelqu'un tente de m'aider sur mon problème épineux. Pour l'instant tu es le seul donc je me permets de t'en dire un peu plus.

En théorie, je suis libre sur la gestion de mes données. Cela m'a amené à revoir la façon d'aborder le problème. Mon but reste d'essayer d'avoir les variation poids et température (pour étudier une corrélation) sur un pas de temps le plus proche possible de la demi-heure.


- 80% de mes données sur près de 600 000 a un pas de temps inférieure à la 1/2h, je me dis que si c'est plus facile, je peux garder uniquement les données qui ont une variation de temps comprise entre 1/2h et 10min. Peut-être cela simplifie le problème?

-J'ai pensé sinon à sommer par pas de 1/2h à partir de l'heure de la date de départ. Par exemple, si la prise de donnée commende le 01/01/2017 à 8:00:00, on somme toutes les lignes allant jusqu'à 01/01/2017 8:30:00, puis on somme toutes les lignes comprises entre 8:30:00 et 9:00:00 etc... Cela me semble plus "carré" et facile à mettre en ouvre dans un premier temps, qu'en penses-tu?
NB: pour cette méthode, il faut bien penser que mes relevés de données ne tombent pas forcement pile sur les demies-heures. Il faut donc que la fonction regarde l'heure des lignes et sache si elle est comprise dans l'intervalle entre 8:00:00 et 8:30:00 par exemple.

Une dernier point, valable pour tout ceux qui souhaite se pencher avec Pierre-Yves et moi sur ce problème:
Mon jeux de donnée comporte des individus ! Voir le nouveau tableau de données ci-dessous avec la colonne "nom" en plus:

Code : Tout sélectionner

#DESCRIPTION DU JEU DE DONNEES
nom <- c("individu1", "individu1","individu1", "individu1","individu1", "individu2", "individu2","individu2", "individu2","individus2")
date.heure <- c("01/01/2017 8:00:00","01/01/2017 8:10:00","01/01/2017 8:25:00","01/01/2017 8:30:00", "01/01/2017 9:10:00", "01/01/2017 8:30:00","01/01/2017 8:40:00","01/01/2017 9:00:00","01/01/2017 9:10:00", "01/01/2017 9:22:00")
poids <- c(20,20.5,22,21,30,30,30.5,32,31,31.5)
temperature <- c(15,16,20,18,26, 20,21,22.5,25,24)
tab <- cbind(nom, date.heure, poids, temperature)
tab

#QUESTION 1 : CALCULER LA VARIATION DE POIDS DE TEMPERATURE ET DE TEMPS EN MINUTE AU COURS DU TEMPS
v.minute <- c(0,10,15,5,40,0,10,20,10,12) 
v.poids <- c(0,0.5,1.5,-1,9, 0,0.5,1.5,-1,0.5)
v.temperature <- c(0,1,4,-2,8, 0,1,1.5,2.5,-1)
tab <- cbind(tab,v.minute, v.poids, v.temperature)
tab

 tab
      nom          date.heure           poids  temperature v.minute v.poids v.temperature
 [1,] "individu1"  "01/01/2017 8:00:00" "20"   "15"        "0"      "0"     "0"         
 [2,] "individu1"  "01/01/2017 8:10:00" "20.5" "16"        "10"     "0.5"   "1"         
 [3,] "individu1"  "01/01/2017 8:25:00" "22"   "20"        "15"     "1.5"   "4"         
 [4,] "individu1"  "01/01/2017 8:30:00" "21"   "18"        "5"      "-1"    "-2"         
 [5,] "individu1"  "01/01/2017 9:10:00" "30"   "26"        "40"     "9"     "8"         
 [6,] "individu2"  "01/01/2017 8:30:00" "30"   "20"        "0"      "0"     "0"         
 [7,] "individu2"  "01/01/2017 8:40:00" "30.5" "21"        "10"     "0.5"   "1"         
 [8,] "individu2"  "01/01/2017 9:00:00" "32"   "22.5"      "20"     "1.5"   "1.5"       
 [9,] "individu2"  "01/01/2017 9:10:00" "31"   "25"        "10"     "-1"    "2.5"       
[10,] "individus2" "01/01/2017 9:22:00" "31.5" "24"        "12"     "0.5"   "-1"     


J'ai oublié de le préciser alors que c'est important. Ainsi toute fonction réalisée doit se faire tant qu'on est avec le même individu, puis on recommence lorsqu'on passe à l'individu suivant. Je pense notamment au calcul de variation proposé par Maxime qui doit être modifié. Je suppose qu'il faudra utiliser un "levels(nom)" quelques part dans la fonction proposée ci-dessous mais impossible de trouver où ...

Code : Tout sélectionner

date.heure <- as.POSIXct(date.heure, format = "%d/%m/%Y %H:%M:%S")
tab <- data.frame(date.heure = date.heure, poids = poids, temperature = temperature)
res <- rbind(0,sapply(lapply(tab, diff), as.numeric))
colnames(res) <- sprintf("v.%s", c("minute", "poids", "temperature"))
res <- cbind(tab, res)
res
           date.heure poids temperature v.minute v.poids v.temperature
1 2017-01-01 08:00:00  20.0          15        0     0.0             0
2 2017-01-01 08:10:00  20.5          16       10     0.5             1
3 2017-01-01 08:25:00  22.0          20       15     1.5             4
4 2017-01-01 08:30:00  21.0          18        5    -1.0            -2
5 2017-01-01 09:10:00  30.0          26       40     9.0             8



Encore une fois, un infinie merci à tous ceux qui voudront bien m'aider. J'essaie d'être réactive au possible pour pouvoir travailler ensemble :)

Coralie

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: calcul de variation au cours du temps

Messagepar Pierre-Yves Berrard » 11 Juil 2017, 08:23

Une proposition avec les groupes simplifiés (intervalles de temps) :

J'ai ajouté "nom" dans les group_by() pour prendre en compte les individus. J'ai également passé l'étape des différences ligne par ligne et juste fait la différence entre la première et dernière ligne du groupe. Enfin, j'ai pris la liberté d'ajouter une colonne "nb.mesures" qui donne le nombre de lignes sommées par groupe et individus.

Si ça fonctionne, on pourra affiner la constitution des groupes.

Données

Code : Tout sélectionner

nom <- c(rep("individu1", 5), rep("individu2", 5))
date.heure <- as.POSIXct(
  c("01/01/2017 8:00:00", "01/01/2017 8:10:00", "01/01/2017 8:25:00",
    "01/01/2017 8:30:00", "01/01/2017 9:10:00", "01/01/2017 8:30:00",
    "01/01/2017 8:40:00", "01/01/2017 9:00:00", "01/01/2017 9:10:00",
    "01/01/2017 9:22:00"),
  format = "%d/%m/%Y %H:%M:%S"
)
poids <- c(20, 20.5, 22, 21, 30, 30, 30.5, 32, 31, 31.5)
temperature <- c(15, 16, 20, 18, 26, 20, 21, 22.5, 25, 24)

tab <- data.frame(nom, date.heure, poids, temperature)

Calculs

Code : Tout sélectionner

library(dplyr)

tab_group <-
  tab %>%
  group_by(nom) %>%
  mutate(
    grp30 = findInterval(
      date.heure,
      seq.POSIXt(
        from = min(date.heure),
        to = max(date.heure),
        by = 1800
      )
    )
  )

tab_group %>%
  group_by(nom, grp30) %>%
  summarize(
    nb.mesures = n(),
    v.minute_total = as.integer(last(date.heure) - first(date.heure)),
    v.poids_total = last(poids) - first(poids),
    v.temperature_total = last(temperature) - first(temperature),
    date.heure_fin = last(date.heure)
  )
PY

Coralie Deniot
Messages : 20
Enregistré le : 04 Nov 2015, 08:09

Re: calcul de variation au cours du temps

Messagepar Coralie Deniot » 11 Juil 2017, 10:20

Re-bonjour Pierre-Yves !

C'est très rassurant de savoir que l'on est épaulée. Je te remercie encore!

J'aurais été incapable d'écrire ce code toute seule. Cela dit mes connaissances sur R me permette de comprendre ce que tu fais:

*C'est une excellente idée d'avoir au préalable créé ce "tab_groupe" qui permet de grouper l'ensemble des lignes qui sont dans la même 1/2h. Maintenant qu'on a ces groupes (by nom, grp30), on peut travailler dessus ce qui ouvre un beau potentiel d'exploitation. Bravo !! Je suis impressionnée :)

*Ensuite tu utilises ces groupes pour justement faire le calcul de variation poids/température/temps. Une très bonne idée! Le tableau obtenu est presque à la hauteur de mes attentes! Tout est impeccable SAUF pour les mesures qui sont "seules" dans une demi-heure.

En effet, ces mesures "seules dans leur demi-heure" se retrouvent avec une variation nulle de poids/température/temps. Pour bien faire, il faudrait que lorsqu'il n'y a que 1 donnée dans la demi-heure, la variation soit calculée en fonction des valeur de la dernière "date.heure_fin".

Par exemple dans notre cas:
Pour l'individu 1 on a : une seule donnée pour la 2ème demi-heure et une seule donnée pour la 3ème demi-heure. Lors du calcul des variations, ces deux données de se différencient avec aucune autre et on a donc une variation nulle.

==> Ce qu'il faudrait avoir pour cette situation, c'est un calcul de la variation entre la donnée unique de la demi-heure (à 8:30:00 un poids à 21Kg, 18°C) et la dernière donnée de la demi-heure qui précède ( à 8:25:00 un poids à 22Kg, 20°C). On aurait donc pour la 2ème demie heure pour cette donnée un "v.minute_total = 5" un "v.poids_total = -1" et un " v.temperature_total = -2".

Certes, on perd le pas de temps de 1 demi-heure (ici on a un V.minute_total de 5 min" mais ce n'est pas un souci. Je préfère cela qu'avoir une variation nulle qui n'est pas réellement correcte.


J'espère sincèrement que mes explications sont claires car je ne souhaite pas abuser de votre temps à la compréhension en plus de votre recherche pour m'aider!
Encore merci et bravo pour cet énorme dégrossissement !! Je suis impressionnée !

Dans l'attente de ton retour pour mon problème soulevé,
Coralie

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: calcul de variation au cours du temps

Messagepar Pierre-Yves Berrard » 11 Juil 2017, 11:56

Coralie Deniot a écrit :J'espère sincèrement que mes explications sont claires car je ne souhaite pas abuser de votre temps à la compréhension en plus de votre recherche pour m'aider!
À part la fourchette de +/-10 min dans le premier post, tout était clair. ;-)

Une amélioration, en recalculant les évolutions par individu ligne par ligne et en les sommant (votre idée initiale, en somme) :

Code : Tout sélectionner

tab_group <-
  tab %>%
  group_by(nom) %>%
  mutate(
    v.date_heure = c(NA, diff(date.heure)),
    v.poids = c(NA, diff(poids)),
    v.temperature = c(NA, diff(temperature)),
    grp30 = findInterval(
      date.heure,
      seq.POSIXt(
        from = min(date.heure),
        to = max(date.heure),
        by = 1800
      )
    )
  )

tab_group %>%
  group_by(nom, grp30) %>%
  summarize(
    nb.mesures = n(),
    v.date_heure_total = sum(v.date_heure, na.rm = TRUE),
    v.poids_total = sum(v.poids, na.rm = TRUE),
    v.temperature_total = sum(v.temperature, na.rm = TRUE),
    date.heure_fin = last(date.heure)
  )
PY

Coralie Deniot
Messages : 20
Enregistré le : 04 Nov 2015, 08:09

Re: calcul de variation au cours du temps

Messagepar Coralie Deniot » 11 Juil 2017, 12:32

Eh bien je n'ai rien à redire ... si ce n'est CHAPEAU ! :)
Vous avez une très bonne maîtrise (de ma perspective) de la manipulation de données sous R et c'est fort aimable à vous de nous en faire part. Je comprends ce que vous faites même si je n'étais pas capable de le mettre en forme.

Je vais adapter l'ensemble à mon jeu de donnée réel mais a priori tout devrait fonctionner. S'il y a un quelconque "couac" je reviendrais en discuter avec vous.

Un dernier point : Comment obtenir le résultat sous forme de matrice? La fonction "summarize" nous affiche simplement le résultat mais pour exploiter les données j'ai besoin de les avoir sous forme de tableau :)

Cela est peut-être très évident et j'avoue me reposer peut-être un peu sur votre aide et votre présence aujourd'hui pour cette dernière question.

Au plaisir de travailler encore avec vous,
Coralie

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: calcul de variation au cours du temps

Messagepar Pierre-Yves Berrard » 11 Juil 2017, 13:44

Pour sauvegarder le "tableau", il faut lui donner un nom :

Code : Tout sélectionner

resultat <-
  tab_group %>%
  group_by(nom, grp30) %>%
  summarize(
    ...

Pas de problème pour répondre à d'autres questions ;-)
PY


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité