Index et comptage de changement de catégorie

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

Christian Vayssier
Messages : 44
Enregistré le : 11 Mai 2009, 08:44

Index et comptage de changement de catégorie

Messagepar Christian Vayssier » 23 Nov 2017, 17:39

Bonjour,

Je suis vraiment bloqué, je voudrais créer une variable pour pouvoir compter le nombre de ligne entre deux type d'événements.
Je m'explique, ma table ressemble à ça :

ID Event
001 A
001 A
001 B
001 B
001 B
001 A
001 B
001 A
001 B
001 B
001 B
001 B
001 B
001 B
001 A

002 B
002 A
002 B
002 B
002 A
002 A
002 B
002 A
002 A
002 A
002 B
002 B
002 A
002 B
002 A

Je voudrais connaitre le nombre de ligne (donc le nombre de B) compris entre 2 "A" pour chacun des identifiants. Je souhaiterais obtenir quelque chose comme cela :

ID Event Comptage
001 A
001 A 3
001 B
001 B
001 B
001 A 1
001 B
001 A 6
001 B
001 B
001 B
001 B
001 B
001 B
001 A

002 B
002 A 2
002 B
002 B
002 A
002 A 1
002 B
002 A
002 A
002 A 2
002 B
002 B
002 A 1
002 B
002 A

J'ai pensé au début a indexé chaque changement puis faire un group by mais je n'y arrive pas du tout.
Quelqu'un aurait il une idée svp ?
Merci.

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

Re: Index et comptage de changement de catégorie

Messagepar Pierre-Yves Berrard » 23 Nov 2017, 20:07

Une idée (peut-être un peu poussive) :

Code : Tout sélectionner

library(purrr)
library(dplyr)

rle_id <-
  tapply(donnees$Event, donnees$ID, rle) %>%
  transpose() %>%
  map(unlist, use.names = FALSE)

pos <- with(rle_id, cumsum(lengths)[values == "A"])
compt <- with(rle_id, lengths[values == "B"])

donnees$Comptage <- NA
donnees$Comptage[pos[seq(compt)]] <- compt
PY

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

Re: Index et comptage de changement de catégorie

Messagepar Gabriel Terraz » 24 Nov 2017, 08:47

Salut,
Quelque chose qui me paraît moins poussif, et sans package :

Jeu de données :

Code : Tout sélectionner

tab <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L), Event = structure(c(1L, 1L, 2L, 2L, 2L,
1L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L), .Label = c("A", "B"), class = "factor")), .Names = c("ID",
"Event"), class = "data.frame", row.names = c(NA, -15L))


Code :

Code : Tout sélectionner

tab$Comptage <- NA ## Ou la valeur que tu veux
colle <- paste(tab$Event, collapse = "")
gr <- gregexpr("AB", colle) ## On choppe l'index des transitions
rl <- rle(as.character(tab$Event)) ## On compte le nombre de répétitions
tab$Comptage[unlist(gr)] <- rl$lengths[rl$values == "B"]


Résultat :

Code : Tout sélectionner

> tab
   ID Event Comptage
1   1     A       NA
2   1     A        3
3   1     B       NA
4   1     B       NA
5   1     B       NA
6   1     A        1
7   1     B       NA
8   1     A        6
9   1     B       NA
10  1     B       NA
11  1     B       NA
12  1     B       NA
13  1     B       NA
14  1     B       NA
15  1     A       NA

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

Re: Index et comptage de changement de catégorie

Messagepar Pierre-Yves Berrard » 24 Nov 2017, 09:02

Gabriel, c'est effectivement plus élégant avec gregexpr.

En revanche, il me semble que ta solution prend en compte à tort une transition "AB", avec A pour l'identifiant 001 et B pour l'identifiant 002 (c'est pour cette raison que j'avais utilisé tapply et purrr::transpose).
PY

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

Re: Index et comptage de changement de catégorie

Messagepar Gabriel Terraz » 24 Nov 2017, 09:12

Un truc doit m'échapper car je ne vois pas ce que tu veux dire Pierre-Yves !

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

Re: Index et comptage de changement de catégorie

Messagepar Pierre-Yves Berrard » 24 Nov 2017, 09:23

Dans l'exemple de Christian, il y a plusieurs ID et le traitement sur les répétitions doit se faire pour chaque ID séparément.

Par exemple, "Comptage" doit être vide pour la dernière ligne de l'identifiant 001, mais avec ton code il semble qu'il va valoir 1 car il y a un B qui suit (mais pour un autre ID).
PY

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

Re: Index et comptage de changement de catégorie

Messagepar Gabriel Terraz » 24 Nov 2017, 09:51

Ok, je pensais que c'étaient des dataframes différents comme il y avait une ligne de vide entre les deux. Effectivement un petit tapply, by ou aggregate devrait réparer le problème.

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

Re: Index et comptage de changement de catégorie

Messagepar Gabriel Terraz » 24 Nov 2017, 13:05

Voilà un truc plus robuste :

df <- structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 2L), Event = structure(c(1L, 1L, 2L, 2L, 2L, 1L,
2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 2L,
1L, 1L, 1L, 2L, 2L, 1L, 2L, 1L), .Label = c("A", "B"), class = "factor")), .Names = c("ID",
"Event"), row.names = c(NA, -30L), class = "data.frame")

Code : Tout sélectionner

f <- function(dataframe){
   dataframe$Comptage <- NA
   colle <- paste(dataframe$Event, collapse = "")
   gr <- gregexpr("AB+", colle)
   dataframe$Comptage[unlist(gr)] <- attr(gr[[1]], "match.length") - 1
   dataframe
}



Et en fonction d'un indice :

Code : Tout sélectionner

bb <- by(df, df$ID, f)
do.call(rbind, bb)


Code : Tout sélectionner

> do.call(rbind,bb)
     ID Event Comptage
1.1   1     A       NA
1.2   1     A        3
1.3   1     B       NA
1.4   1     B       NA
1.5   1     B       NA
1.6   1     A        1
1.7   1     B       NA
1.8   1     A        6
1.9   1     B       NA
1.10  1     B       NA
1.11  1     B       NA
1.12  1     B       NA
1.13  1     B       NA
1.14  1     B       NA
1.15  1     A       NA
2.16  2     B       NA
2.17  2     A        2
2.18  2     B       NA
2.19  2     B       NA
2.20  2     A       NA
2.21  2     A        1
2.22  2     B       NA
2.23  2     A       NA
2.24  2     A       NA
2.25  2     A        2
2.26  2     B       NA
2.27  2     B       NA
2.28  2     A        1
2.29  2     B       NA
2.30  2     A       NA

Christian Vayssier
Messages : 44
Enregistré le : 11 Mai 2009, 08:44

Re: Index et comptage de changement de catégorie

Messagepar Christian Vayssier » 28 Nov 2017, 10:11

Bonjour Pierre-Yves, bonjour Gabriel,

Je viens de tester, ça marche super bien. Merci beaucoup à vous deux pour votre aide et le temps accordé.
ça m'a vraiment bien débloqué.

+++


Retourner vers « Questions en cours »

Qui est en ligne

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