« Questions-r » : différence entre les versions

Aller à la navigation Aller à la recherche
2 347 octets enlevés ,  10 janvier 2022
arrange question martiste
(rajout en vrac)
(arrange question martiste)
Ligne 66 : Ligne 66 :
Regarde ?na.approx pour plus de détails sur son fonctionnement
Regarde ?na.approx pour plus de détails sur son fonctionnement


== Programmation fonctionnelle
== Programmation fonctionnelle ==


Question de martiste
'''Question de martiste'''


J'ai un jeu de données avec des températures à pas de temps horaire, le tout sur plusieurs années (et plusieurs stations). J'aimerais connaître, pour chaque année et pour chaque station, le nombre de séquences où la température a dépassé les 19°C, ainsi que la durée de la séquence la plus longue. Avec une boucle, j'aurais créé un nouveau champ pour lequel j'incrémente une valeur de séquence à chaque fois que T>19 et que T-1<19. Je regarde la valeur max de ma séquence, et la longueur max de ces séquences également. Mais comment faire sans boucle ?
J'ai un jeu de données avec des températures à pas de temps horaire, le tout sur plusieurs années (et plusieurs stations). J'aimerais connaître, pour chaque année et pour chaque station, le nombre de séquences où la température a dépassé les 19°C, ainsi que la durée de la séquence la plus longue. Avec une boucle, j'aurais créé un nouveau champ pour lequel j'incrémente une valeur de séquence à chaque fois que T>19 et que T-1<19. Je regarde la valeur max de ma séquence, et la longueur max de ces séquences également. Mais comment faire sans boucle ?


dat <- readxl::read_excel("~/Téléchargements/BIE0-3_donnees.xlsx")
'''Réponse de lvaudor'''
library(dplyr)
result=dat %>%
  mutate(hot=chmes_valeur>19) %>%
  mutate(hot_prev=lag(hot,1)) %>%
  mutate(change=hot & !hot_prev) %>%
  mutate(sequence=cumsum(change))
faut peaufiner, ça fait pas exactement ce qu'il faut
faudrait aussi faire le changement "inverse", quand il fait pas chaud et qu'il faisait chaud avant
pour isoler toutes les "séquences", chaudes ou froides
Faut aussi bien faire en sorte que tout soit rangé dans l'ordre temporel avant de faire tourner le truc (ce qui n'est pas le cas ici, vu que j'ai pas groupé par station par exemple)


martiste  23/08/2021
<syntaxhighlight lang="r">
Ouip
Alors, une fois trié et groupé, j'étais parti sur ça :
dat %>%
  mutate(seq = case_when(chmes_valeur> 19 & lag(chmes_valeur<= 19) ~ 1,
                        chmes_valeur> 19 & lag(chmes_valeur> 19) ~ 1,
        TRUE ~ 0))
Ca m'isole mes séquences, mais pas d'incréments
LiseV — 23/08/2021
et quand tu essaies comme ça, ça fonctionne?
martiste — 23/08/2021
Non
LiseV — 23/08/2021
hmmm
tu lui as bien refait "tourner" la déf de la fonction?
martiste — 23/08/2021
rreur : Problem with mutate() column data.
i data = purrr::map_dfr(data, get_sequences(., Temp = 19)).
x Problem with mutate() column change.
i change = case_when(chmes_valeur > Temp & lag(chmes_valeur <= Temp) ~ 1, TRUE ~ 0).
x objet 'chmes_valeur ' introuvable
LiseV — 23/08/2021
pour écraser l'ancienne "get_sequences() par la nouvelle??
martiste — 23/08/2021
Moui...
LiseV — 23/08/2021
hihi
ça valait le coup de demander, on sait jamais
je vois pourquoi le map fonctionne pas, pas pourquoi l'appel simple fonctionne pas
Chez moi, ça, ça fonctionne:
get_sequences=function(donnees, Temp){
get_sequences=function(donnees, Temp){
   result = donnees %>%  
   result = donnees %>%  
Ligne 127 : Ligne 88 :
   mutate(data=purrr::map(data,get_sequences,Temp=19)) %>%  
   mutate(data=purrr::map(data,get_sequences,Temp=19)) %>%  
   tidyr::unnest(cols=c(data))
   tidyr::unnest(cols=c(data))
</syntaxhighlight>
ou bien (autre syntaxe possible pour map), comme ça:
ou bien (autre syntaxe possible pour map), comme ça:
<syntaxhighlight lang="r">
result= dat %>%  
result= dat %>%  
   group_by(chmes_coderhj,chmes_anneebiol) %>%  
   group_by(chmes_coderhj,chmes_anneebiol) %>%  
Ligne 133 : Ligne 98 :
   mutate(data=purrr::map(data,~get_sequences(.,Temp=19))) %>%  
   mutate(data=purrr::map(data,~get_sequences(.,Temp=19))) %>%  
   tidyr::unnest(cols=c(data))
   tidyr::unnest(cols=c(data))
martiste — 23/08/2021
 
Magique !
Différence entre avec et sans '~' devant la fonction:
Tu saurais dire la différence entre les deux ?!
 
LiseV — 23/08/2021
* soit map attend le nom d'une fonction
entre ta version et ma version?
: Dans ce cas l'argument sur lequel il itère doit être le premier argument de la fonction
martiste — 23/08/2021
* soit map attend une formule (précédée d'un "~", donc)
Entre avec et sans '~' devant la fct
: Dans ce cas il y a un peu plus de souplesse sur la position de l'argument sur lequel on itère
LiseV — 23/08/2021
 
ou entre la syntaxe 1 et la syntaxe 2?
ben tu l'as, la différence, c'est le "~", lol
soit map attend le nom d'une fonction
dans ce cas l'argument sur lequel il itère doit être le premier argument de la fonction
soit map attend une formule (précédée d'un "~", donc)
dans ce cas il y a un peu plus de souplesse sur la position de l'argument sur lequel on itère
Tu pourrais dire ~ get_sequences(data, Temp=.) pour itérer sur une variable qui donnerait un seuil de température, par exemple
Tu pourrais dire ~ get_sequences(data, Temp=.) pour itérer sur une variable qui donnerait un seuil de température, par exemple
et non plus itérer sur le premier argument, "data"
et non plus itérer sur le premier argument, "data"
(on est d'accord, sur le "fond" du traitement cet exemple n'a guère de sens)
 
martiste — 23/08/2021
😊  mais je pense que j'ai saisi l'essentiel...
Merci !
LiseV — 23/08/2021
Si tu donnes le nom de la fonction, tu peux quand-même rajouter des arguments "secondaires"
Si tu donnes le nom de la fonction, tu peux quand-même rajouter des arguments "secondaires"
mais tu les rajoutes directement comme arguments optionnels à la fonction "map", pas dans un simulacre d'appel à la fonction que tu itères
mais tu les rajoutes directement comme arguments optionnels à la fonction "map", pas dans un simulacre d'appel à la fonction que tu itères
C'est un peu compliqué ces histoires de syntaxe mais une fois que c'est acquis c'est bien pratique 😉
 
Dans un cas "simple" (comme ici) il vaut mieux utiliser la première syntaxe je trouve
c'est ce qui est prévu "par défaut" pour faire tourner purrr::map
L'utilisation des formules c'est un subtilité introduite pour gérer les fonctions qui n'ont pas les arguments "dans l'ordre le plus pratique au regard de ce qu'on souhaite faire".  
L'utilisation des formules c'est un subtilité introduite pour gérer les fonctions qui n'ont pas les arguments "dans l'ordre le plus pratique au regard de ce qu'on souhaite faire".  
martiste — 23/08/2021
 
Okay, bien reçu m'dame !
 
martiste — 23/08/2021
Et, pour finir, si je veux en sortir 1) le nombre total de séquences, et 2) la durée de la séquence la plus longue, est-ce que tu me conseilles de l'inclure dans la fct 'get_sequences', ou de repartir des résultats de cette fonction et d'alimenter une nouvelle ?
Et, pour finir, si je veux en sortir 1) le nombre total de séquences, et 2) la durée de la séquence la plus longue, est-ce que tu me conseilles de l'inclure dans la fct 'get_sequences', ou de repartir des résultats de cette fonction et d'alimenter une nouvelle ?
LiseV — 23/08/2021
LiseV — 23/08/2021
Utilisateur anonyme

Menu de navigation