Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajoutées)

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

François Méric
Messages : 5
Enregistré le : 23 Fév 2023, 09:16

Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajoutées)

Messagepar François Méric » 28 Fév 2023, 16:16

Bonjour à tous et toutes,

J'ai un 1er jeu de données (="Virey") qui représente le niveau d'eau d'une rivière en fonction du temps. Le pas de temps des mesures est de 1h et les dates sont en format numérique Excel car je trouve plus simple de les manipuler (sous Excel: 1 jour = 1, 1h = 0,042).
La chronique est longue donc je mets seulement l'exemple d'une crue :

Code : Tout sélectionner

Virey <- structure(list(Date = c(44716.0417, 44716.0833, 44716.125, 44716.1667,
44716.2083, 44716.25, 44716.2917, 44716.3333, 44716.375, 44716.4167,
44716.4583, 44716.5, 44716.5417, 44716.5833, 44716.625, 44716.6667,
44716.7083, 44716.75, 44716.7917, 44716.8333, 44716.875, 44716.9167,
44716.9583, 44717, 44717.0417, 44717.0833, 44717.125, 44717.1667,
44717.2083, 44717.25, 44717.2917, 44717.3333, 44717.375, 44717.4167,
44717.4583, 44717.5, 44717.5417, 44717.5833, 44717.625, 44717.6667,
44717.7083, 44717.75, 44717.7917, 44717.8333, 44717.875, 44717.9167,
44717.9583, 44718, 44718.0417, 44718.0833, 44718.125, 44718.1667,
44718.2083, 44718.25, 44718.2917, 44718.3333, 44718.375, 44718.4167,
44718.4583, 44718.5, 44718.5417, 44718.5833, 44718.625, 44718.6667,
44718.7083, 44718.75, 44718.7917, 44718.8333, 44718.875, 44718.9167,
44718.9583, 44719, 44719.0417, 44719.0833, 44719.125, 44719.1667,
44719.2083, 44719.25, 44719.2917, 44719.3333, 44719.375, 44719.4167,
44719.4583, 44719.5, 44719.5417, 44719.5833, 44719.625, 44719.6667,
44719.7083, 44719.75, 44719.7917, 44719.8333, 44719.875, 44719.9167,
44719.9583), NivV = c(0.279, 0.279, 0.28, 0.283, 0.286, 0.29,
0.297, 0.301, 0.302, 0.3, 0.297, 0.296, 0.293, 0.289, 0.286,
0.285, 0.282, 0.279, 0.28, 0.285, 0.294, 0.318, 0.572, 0.826,
0.975, 1.114, 1.246, 1.393, 1.57, 1.646, 1.622, 1.492, 1.219,
1.033, 0.905, 0.829, 0.771, 0.726, 0.689, 0.657, 0.628, 0.605,
0.581, 0.559, 0.54, 0.523, 0.509, 0.494, 0.479, 0.465, 0.453,
0.442, 0.431, 0.422, 0.414, 0.408, 0.402, 0.396, 0.391, 0.385,
0.374, 0.368, 0.367, 0.362, 0.358, 0.354, 0.35, 0.348, 0.345,
0.341, 0.336, 0.332, 0.329, 0.326, 0.324, 0.323, 0.321, 0.32,
0.319, 0.318, 0.319, 0.316, 0.316, 0.312, 0.312, 0.313, 0.312,
0.311, 0.309, 0.307, 0.306, 0.306, 0.305, 0.305, 0.305)), row.names = 481:575, class = "data.frame")

A partir de cette chronique, je cherche à repérer les hausses de niveau d'eau synonymes de début de crue. J'ai fixé comme seuil de détection une hausse minimale de 4cm en 1h. J'ai réussi à extraire dans un 2ème dataframe (="Virey_crue") la date et le niveau d'eau pour chacun de ces événements de crue. J'ai ensuite éliminer ceux qui étaient trop proches car seuls les débuts de crue m'intéressent ici (sur cette rivière, les crues durent en moyenne entre 1 et 3 jours donc j'ai pris ici un minimum de 2 jours d'écart entre 2 "débuts" de crue)).

Code : Tout sélectionner

Virey_Date <- c()
Virey_Niv <- c()
# Pour identifier les declenchements de crue
for (i in 2:nrow(Virey)) {
    if(Virey[i,2]-Virey[i-1,2] >= 0.04) { # le 0.04 represente la hausse du niveau d'eau pour identifier une crue (en metres)
    Virey_Date <- c(Virey_Date,Virey[i-1,1])
    Virey_Niv <- c(Virey_Niv,Virey[i-1,2])
    Virey_crue <- data.frame(Virey_Date,Virey_Niv)
    }
}

plot(Virey$Date, Virey$NivV,col="blue",type="l", main="Seuil = 0,04m")
points(Virey_crue$Virey_Date, Virey_crue$Virey_Niv,col="red", pch=19)

# Pour garder seulement les debuts de crue (enlever les declenchements qui se suivent (moins de 2 jours d'ecart)
for (p in 2:nrow(Virey_crue)) {
    while(Virey_crue[p,1]-Virey_crue[p-1,1] < 2) { # sous Excel : 2 = 2 jours
      Virey_crue <- Virey_crue[-p,]
  }
}

plot(Virey$Date, Virey$NivV,col="blue",type="l", main = "Seuil = 0,04m et 48h / n = 12")
points(Virey_crue$Virey_Date, Virey_crue$Virey_Niv,col="red",pch=19)

J'aimerais maintenant simuler un échantillonnage durant chacune de ces crues avec un préleveur automatique qui a une capacité de 24 flacons et qui prélèverait un flacon toutes les 2h (ou 3h).
Je voudrais donc insérer 23 lignes à la suite de chacun de ces débuts de crue, avec un intervalle de 2h entre chaque ligne. Le niveau d'eau peut rester le même pour les 23 lignes (je veux surtout voir si l'ensemble des 24 flacons permet d’échantillonner toute la crue ou pas). Bien sûr, s'il est possible de récupérer le niveau d'eau associé à la date de chaque flacon, ça serait top :)

Merci d'avance et je vous souhaite une très bonne journée,

François

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

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar Pierre-Yves Berrard » 28 Fév 2023, 16:30

Bonjour,

J'ai un doute : il faut insérer les lignes dans Virey ou dans Virey_crue ?

Peut-être fournir le résultat attendu associé aux données exemple.
PY

François Méric
Messages : 5
Enregistré le : 23 Fév 2023, 09:16

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar François Méric » 01 Mar 2023, 07:27

Bonjour,

Je n'ai pas été très clair là-dessus, c'est vrai. Je voudrais les insérer dans Virey_crue sous cette forme :

Code : Tout sélectionner

Ech      Virey_Date       Virey_Niv
crue 1-1     t0               x
crue 1-2    t0+2              x
crue 1-3    t0+4              x
...
crue 1-24   t0+48             x

crue 2-1     t1               x1
crue 2-2    t1+2              x1
crue 2-3    t1+4              x1
...
crue 2-24   t1+48             x1


Bonne journée,
François

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

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar Pierre-Yves Berrard » 01 Mar 2023, 08:35

Si je fais tourner le code du premier message, j'obtiens un Virey_crue où toutes les lignes sont séparées d'une heure :

Code : Tout sélectionner

  Virey_Date Virey_Niv
1   44716.92     0.318
2   44716.96     0.572
3   44717.00     0.826
4   44717.04     0.975
5   44717.08     1.114
6   44717.12     1.246
7   44717.17     1.393
8   44717.21     1.570


Comment insérer les lignes dans cette situation ?
PY

François Méric
Messages : 5
Enregistré le : 23 Fév 2023, 09:16

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar François Méric » 01 Mar 2023, 08:57

Les dates que vous avez correspondent à toutes les hausses de 0,04m en moins d'une heure. Avec la suite de code, j'élimine les dates qui se suivent (celles qui sont séparées de moins de 48h) :

Code : Tout sélectionner

# Pour garder seulement les debuts de crue (enlever les declenchements qui se suivent (moins de 2 jours d'ecart)
for (p in 2:nrow(Virey_crue)) {
    while(Virey_crue[p,1]-Virey_crue[p-1,1] < 2) { # sous Excel : 2 = 2 jours
      Virey_crue <- Virey_crue[-p,]
  }
}

Normalement, vous ne devriez avoir plus qu'une seule date :

Code : Tout sélectionner

 Virey_Date Virey_Niv
1 44716.92 0.318

François

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

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar Pierre-Yves Berrard » 01 Mar 2023, 09:10

Effectivement, j'ai oublié d'exécuter la fin du code (NB : ce gros bloc de code ne fait qu'embrouiller la compréhension puisqu'au final seul Virey_crue sert)

On est d'accord qu'il peut y avoir plusieurs lignes ?

Donc un data.frame plus représentatif serait sous cette forme ?

Code : Tout sélectionner

Virey_crue <- data.frame(
  Virey_Date = c(44716.9167, 45000),
  Virey_Niv  = c(0.318, 1)
)
PY

François Méric
Messages : 5
Enregistré le : 23 Fév 2023, 09:16

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar François Méric » 01 Mar 2023, 09:21

J'ai préféré tout mettre pour être le plus complet possible.
Oui oui il peut y avoir plusieurs lignes. Ici vous n'en avez qu'une car je n'ai mis qu'un bout de ma chronique (une seule crue). Mais ma chronique est bien plus longue et j'obtiens à la fin une ligne par crue.

François

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

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar Pierre-Yves Berrard » 01 Mar 2023, 09:28

Une proposition avec un jeu de données fictif à 3 crues :

Code : Tout sélectionner

# données fictives
Virey_crue <- data.frame(
  Virey_Date = c(44716.9167, 45000, 45100),
  Virey_Niv  = c(0.318, 1, 0.5)
)

# fonction traitant un data.frame contenant une seule date (une seule ligne)
replique_1_date <- function(d, nb_heures = 2) {
  data.frame(
    Virey_Date = seq(from = d$Virey_Date, length.out = 24, by = nb_heures / 24),
    Virey_Niv  = rep(d$Virey_Niv, 24)
  )
}

# applique à toutes les dates
liste_df <-
  lapply(
    split(Virey_crue, Virey_crue$Virey_Date),
    replique_1_date,
    nb_heures = 2
  
)

# agregation de tous les data.frame de la liste
resultat <- do.call(rbind, unname(liste_df))
PY

François Méric
Messages : 5
Enregistré le : 23 Fév 2023, 09:16

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar François Méric » 01 Mar 2023, 09:50

C'est effectivement le résultat que je recherchais.
Merci beaucoup Pierre-Yves.
Très bonne journée,
François

Maxime Deniaux
Messages : 68
Enregistré le : 11 Fév 2022, 22:49
Contact :

Re: Insérer plusieurs lignes à plusieurs endroits d'un data frame (avec un pas de temps identique entre les lignes ajout

Messagepar Maxime Deniaux » 01 Mar 2023, 10:54

Pierre-Yves Berrard a écrit :Une proposition avec un jeu de données fictif à 3 crues :

Code : Tout sélectionner

# données fictives
Virey_crue <- data.frame(
  Virey_Date = c(44716.9167, 45000, 45100),
  Virey_Niv  = c(0.318, 1, 0.5)
)

# fonction traitant un data.frame contenant une seule date (une seule ligne)
replique_1_date <- function(d, nb_heures = 2) {
  data.frame(
    Virey_Date = seq(from = d$Virey_Date, length.out = 24, by = nb_heures / 24),
    Virey_Niv  = rep(d$Virey_Niv, 24)
  )
}

# applique à toutes les dates
liste_df <-
  lapply(
    split(Virey_crue, Virey_crue$Virey_Date),
    replique_1_date,
    nb_heures = 2
  
)

# agregation de tous les data.frame de la liste
resultat <- do.call(rbind, unname(liste_df))



!!!! Pierre-Yves, comment tu mets en couleurs du texte dans un bloc de code ? C'est super clean :)

J'avais essayé de la même façon qu'en dehors d'un bloc de code, mais ça ne fonctionnait pas. J'ai loupé quoi ?

Edit :

Code : Tout sélectionner

 # Ok il faut ajouter  = php dans le premier [code = php]     


Merci !


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité