Répétition lignes

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

Audrey Winter
Messages : 97
Enregistré le : 12 Mai 2014, 15:17

Répétition lignes

Messagepar Audrey Winter » 10 Mar 2017, 18:35

Bonsoir,
J'ai une base de données qui par ligne me donne un voltage - une date de début - une date de fin.

J'aimerai répéter chaque ligne de la sorte :

Code : Tout sélectionner

2.5     2011-06-22        2011-06-25


deviendrait (avec la création d'une nouvelle variable date) :

Code : Tout sélectionner

2.5     2011-06-22       
2.5     2011-06-23       
2.5     2011-06-24       
2.5     2011-06-25         


Pour avoir une occurrence par jour.
Quelqu'un aurait-il une idée pour pouvoir implémenter ce genre de procédure sur la base entière (sachant que l'écart entre la date de début et la date de fin n'est jamais le même). Peut-être faudrait-il créer un nouveau data...
Merci !

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

Re: Répétition lignes

Messagepar Pierre-Yves Berrard » 10 Mar 2017, 22:06

Bonsoir,

Une solution pas forcément simple pour un débutant, mais avec plein de bonnes choses dedans (apply, sapply, do.call...)

Code : Tout sélectionner

# données test
ma_base <- data.frame(
  voltage = c(2.5, 4.5, 7.0),
  debut   = as.Date(c("2017-03-01", "2017-03-03", "2017-03-06")),
  fin     = as.Date(c("2017-03-02", "2017-03-05", "2017-03-06"))
)

Code : Tout sélectionner

# génère les séries de dates qui seront mises en colonne par la suite

dates <- apply(
  ma_base[ , c("debut", "fin")],
  MARGIN = 1,
  function(x) seq(as.Date(x[1]), as.Date(x[2]), by = "days")
)

nb_dates <- sapply(dates, length)

# construction du data.frame final

data.frame(
  voltage = rep(ma_base$voltage, nb_dates),
  date = do.call(c, dates)
)
PY

Audrey Winter
Messages : 97
Enregistré le : 12 Mai 2014, 15:17

Re: Répétition lignes

Messagepar Audrey Winter » 12 Mar 2017, 11:31

merci !
effectivement j'étais parti dans quelque chose de similaire en calculant l'écart entre la date de début et celle de fin pour avoir le nombre d’occurrence de chacun des sujets et après je voulais ajouter +1j à chaque date mais mon code est beaucoup plus long ! je n'ai pas l'habitude d'utiliser apply()... il faut absolument que je prenne cette habitude!

Par contre j'ai un problème avec do.call :

Code : Tout sélectionner

Error in do.call(c, dates) :
  'what' must be a function or character string
 


il faut que je mette la fonction c entre guillemets pour que ça fonctionne ...

Merci beaucoup à vous !

Gabriel Terraz
Messages : 591
Enregistré le : 26 Sep 2011, 15:11

Re: Répétition lignes

Messagepar Gabriel Terraz » 12 Mar 2017, 13:18

Salut,

Une petite variante avec mapply qui me semble plus approprié que apply dans ce cas là :

Code : Tout sélectionner

mp <- mapply(seq, ma_base$debut, ma_base$fin, by ="days")

Paul Valentine
Messages : 4
Enregistré le : 30 Jan 2017, 09:53

Re: Répétition lignes

Messagepar Paul Valentine » 12 Mar 2017, 14:44

Bonjour,

Pour le problème que tu as rencontré, il semble que tu aies déjà créé un objet qui s'appelle c.
c() étant déjà une fonction de base de R, il est primordial de ne jamais utiliser ce nom (de même pour t, je te conseille de ne jamais appeler un objet ou une nouvelle fonction comme cela).

Petit conseil. Lorsque tu souhaites créer un nouvel objet ou une nouvelle fonction, exécute toujours son nom avant de lui attribuer une valeur. Petit exemple avec la fonction floor() qui calcule la partie entière et qui est déjà une fonction de base de R (comme on peut le voir en lançant la commande floor)

Code : Tout sélectionner

> floor
function (x)  .Primitive("floor")
> floor(3.141592)
[1] 3
> floor<-function(x){
+     return(exp(x))
+   }
> floor(3.141592)
[1] 23.14068
> rm(list=ls())
> floor(3.141592)
[1] 3

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

Re: Répétition lignes

Messagepar Pierre-Yves Berrard » 13 Mar 2017, 09:56

Avec l'amélioration de Gabriel (mapply) et les guillements dans do.call pour être tranquille, on obtient un code assez succinct :

Code : Tout sélectionner

dates <- mapply(seq, ma_base$debut, ma_base$fin, by ="days")
data.frame(
  voltage = rep(ma_base$voltage, sapply(dates, length)),
  date = do.call("c", dates)
)
PY


Retourner vers « Questions en cours »

Qui est en ligne

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