fusionner niveaux d'un facteur en un autre niveau

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

Tomas leon
Messages : 51
Enregistré le : 09 Jan 2018, 16:12

fusionner niveaux d'un facteur en un autre niveau

Messagepar Tomas leon » 15 Fév 2018, 09:59

Bonjour à tous,

J'ai une question technique pour vous s'il vous plaît.

Je travaille sur un jeu de donnée d'observation d'oiseaux. Lors d'une séance de comptage, le technicien traverse plusieurs parcelles, et compte les oiseaux. Sauf que dans mon jeu de données, je n'ai pas l'information "nombre d'oiseaux par parcelle" mais "nombre d'oiseaux par séance" (il peut y avoir plusieurs séances par jour, en général 3). J'ai plusieurs années de données et en tout il y a 700 parcelles sur mon domaine. Lorsque le technicien fait une séance de comptage, il traverse les parcelles qui se touchent (logique). Et, souvent, les mêmes groupes de parcelles sont visités.

Code : Tout sélectionner

Date         seance   parcelle Surf   Sais   oiseaux
2004-10-30       1      279   13.52 Saison1   55
2004-10-30       1      280   14.04 Saison1   55
2004-10-30       1      281   14.21 Saison1   55
2004-10-30       2      282   13.51 Saison1   45
2004-10-30       2      283   14.27 Saison1   45
2004-10-30       2      284   14.27 Saison1   45


Ma question est : est-il possible de faire une manipulation sous R qui me permettrait de fusionner les niveaux des parcelles dans une nouvelle variable ? Du genre ici parcelle "279", "280" et "281" vont devenir un groupe AAA, et "282", "283", "284" vont devenir un autre groupe AAB etc. Sachant que ces combinaisons vont sans doute revenir dans le jeu de données. Ici je passerais de 700 parcelles à, imaginons, 150 groupes de parcelles (AAA, AAB, AAC etc...), que je vais pouvoir comparer en fonction de leurs scores d'oiseaux comptés (pour savoir a terme s'il y a des groupes de parcelles dans lesquels il y a souvent plus d'oiseaux comptés --> in fine, le groupe AAB est le groupe où il y a le plus d'oiseaux comptés, ou bien que le groupe de parcelle le plus visité c'est le AAC avec 32 visites, etc, etc.)

Je ne sais pas si cette transformation est possible. Mais si elle est possible, pensez-vous qu'il serait possible de vérifier dans chacun des nouveaux groupes créés, quelles parcelles il représente (dans les attributions ? ou bien peut-être en générant un tableau récapitulatif que je pourrais consulter), pour que je puisse savoir que AAA = "279", "280" et "281".

Merci pour vos aides !

Bastien Gamboa
Messages : 151
Enregistré le : 13 Jan 2011, 21:31

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Bastien Gamboa » 15 Fév 2018, 10:27

Bonjour,

Peux-tu expliciter un peu plus les critères pour la création de cette nouvelle variable et/ou changer les données exemples ?
En effet pour le moment, avec les données exemple il semble que ta nouvelle variable soit la variable seance (valant 1 pour les 3 premières parcelles à la place de AAA comme tu le souhaites, et 2 pour les 3 suivantes à la place de AAB).

Bastien

Tomas leon
Messages : 51
Enregistré le : 09 Jan 2018, 16:12

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Tomas leon » 15 Fév 2018, 10:50

Salut,

Dans mon post d'avant les AAA, AAB sont des exemples de noms de variables, mais si on les transformes en groupe "1", groupe "2" etc peu m'importe :)

L'idée ici ce serait de créer une variable (en facteur) qui attribuerait un niveau lorsqu'il reconnaitrait une combinaison spécifique de parcelles. Dans mon exemple, la visite de "279", "280" et "281" pourrait avoir lieu plusieurs fois au cours de mes saisons de comptage, exactement de la façon "279", "280" et "281". Donc je voudrais que "279", "280" et "281" devienne un niveau d'un facteur d'une variable qu'il faudrait créer. Il faudrait demander à R : "quand c'est "279", "280" et "281" dans la variable "parcelle", tu mets dans une variable "groupe" un level "1", etc...". Mais il faudrait qu'il le fasse automatique, j'ai trop de données pour le faire manuellement.... Ainsi j'aurais les scores de comptages en fonction d'un groupe de parcelles qui serait susceptible d'avoir été visité plusieurs fois.

Pour mon jeu de données, j'ai 14 000 lignes et je ne sais pas si montrer plus de mon jeu de données ici serait intéressant, puisque si ça se trouve, pour identifier que plusieurs groupes arrivent plusieurs fois, il faudrait des milliers de lignes....

Cela me fait penser que cette variable "groupe" ne pourra pas être directement dans mon data.frame. Il faudrait voir si on peut stoker ces infos dans un vecteur. Puis il faudra que je "contracte" mon jeu de données pour avoir 1 ligne = 1 séance (associée à sa date) et non plus 1 ligne = 1 parcelle (j'avais déjà fait une manip comme ça pour sommer les surfaces de mes parcelles en fonction des séances), et ensuite y greffer la variable "groupe" qui aura du coup, je l'espère, moins de niveaux que ma variable parcelle qui en à 700, puisque les combinaisons ne sont pas sensées être unique.


Encore merci :D

Bastien Gamboa
Messages : 151
Enregistré le : 13 Jan 2011, 21:31

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Bastien Gamboa » 15 Fév 2018, 11:14

Bonjour,

Voici une première idée basée sur table() et sur le fait que les combinaisons des parcelles sont définies par 'parcelle' et par 'seance' :

Code : Tout sélectionner

truc <- read.table(text="Date         seance   parcelle Surf   Sais   oiseaux
2004-10-30       1      279   13.52 Saison1   55
2004-10-30       1      280   14.04 Saison1   55
2004-10-30       1      281   14.21 Saison1   55
2004-10-30       2      282   13.51 Saison1   45
2004-10-30       2      283   14.27 Saison1   45", header=TRUE)

# Trouver les combinaisons de parcelles
temp <- t(table(truc$seance, truc$parcelle))
# Noms automatiques
colnames(temp) <- paste0(rep(LETTERS, each=length(LETTERS)), rep(LETTERS, times=length(LETTERS)))[1:ncol(temp)]
# Remplacement des 1 par les numéros de parcelles
sum(temp>1) # est censé être 0 si je comprend bien tes données. Et doit l'être pour la ligne ci-dessous
temp <- temp*as.numeric(rownames(temp))
# Suppression des 0
combinaisons <- apply(temp, 2, FUN=function(x) x[x!=0] )

Est-ce qu'on se rapproche de ce que tu souhaites ?

Bastien

Tomas leon
Messages : 51
Enregistré le : 09 Jan 2018, 16:12

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Tomas leon » 15 Fév 2018, 13:02

Salut Bastien,

Merci pour t'as réponse rapide,

Je viens d'essayer sur le premier jour de mes données, ça fonctionne.

Cependant, serait-il possible de faire une distinction entre les journées ? Puisque il y a une séance "1" à chaque nouvelle journée de comptage.

Avant on avait ça :

Code : Tout sélectionner

Date         seance   parcelle Surf   Sais   oiseaux
2004-10-30       1      279   13.52 Saison1   55
2004-10-30       1      280   14.04 Saison1   55
2004-10-30       1      281   14.21 Saison1   55
2004-10-30       2      282   13.51 Saison1   45
2004-10-30       2      283   14.27 Saison1   45
2004-10-30       2      284   14.27 Saison1   45


et finalement ce que j'aimerai obtenir c'est ça :

Code : Tout sélectionner

Date         seance  groupe Surf   Sais   oiseaux
2004-10-30       1      AA   41.77 Saison1   55
2004-10-30       2      AB   42.05 Saison1   45
2004-11-01       1      AC   48.77 Saison1   34
2004-11-01       2      AA   41.77 Saison1   28


Sachant que j'ai déjà un data qui à subit une transformation de parcelle --> en séance (avec 1 ligne = 1 séance avec les surfaces des parcelles sommées pour avoir 1 valeur). Il ne me restera plus qu'à y coller la variable "groupe"

De plus, je m'éloigne peut être un peu de la question initiale : ton "combinaisons" renvoie a des listes, ce qui est top pour regarder ce qu'il y a à l'intérieur, mais, une fois tout le processus terminé, est ce qu'il sera possible de vérifier le % de ressemblance entre les groupes ? Ca se trouve, les parcelles AAAC et AABE ne vont différer que d'une parcelle et donc s'ils sont trop ressemblant, à terme je pourrais décider de les fusionner parce qu'en gros ce sera la même zone.

Encore merci !

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

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Pierre-Yves Berrard » 15 Fév 2018, 15:56

Tomas leon a écrit :ton "combinaisons" renvoie a des listes, ce qui est top pour regarder ce qu'il y a à l'intérieur, mais, une fois tout le processus terminé, est ce qu'il sera possible de vérifier le % de ressemblance entre les groupes ?


Bonjour,

Ça devrait être possible. Par exemple :

Code : Tout sélectionner

pct_commun <- function(x, y) length(intersect(x, y)) / length(union(x, y)) * 100

grp <- list(A = 1:5, B = 2:5, C = 0:1, D = 2, E = 4:9)
n <- length(grp)

res <- matrix(nrow = n, ncol = n, dimnames = list(names(grp), names(grp)))
for (i in 1:n) for (j in 1:i) res[i, j] <- pct_commun(grp[[i]], grp[[j]])

round(res)
rm(i, j, n)

Résultat :

Code : Tout sélectionner

    A   B   C   D   E
A 100  NA  NA  NA  NA
B  80 100  NA  NA  NA
C  17   0 100  NA  NA
D  20  25   0 100  NA
E  22  25   0   0 100
PY

Tomas leon
Messages : 51
Enregistré le : 09 Jan 2018, 16:12

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Tomas leon » 16 Fév 2018, 07:50

Salut Pierre-Yves,

Merci d'avoir répondu à ma question bonus :)

Quelqu'un aurait une idée pour ma transformation du haut s'il vous plait :D ?

Encore merci !

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

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Pierre-Yves Berrard » 16 Fév 2018, 08:38

En reprenant les données truc de Bastien :

Code : Tout sélectionner

library(dplyr)

comb_df <-
  truc %>%
  group_by(Date, seance) %>%
  summarise(combinaisons = list(parcelle))
 
comb_df$combinaisons

Il manque juste le nommage des éléments.
PY

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

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Logez Maxime » 16 Fév 2018, 09:36

Bonjour,

une possibilité :

Code : Tout sélectionner

truc2 <- truc %>% group_by(Date, seance) %>% arrange(parcelle) %>%
  summarise(parcelle = paste(parcelle, collapse="_"), Surf = sum(Surf), Sais = Sais[1], oiseaux = oiseaux[1])

auxi <- data.frame(parcelle = sort(unique(truc2$parcelle)))

ncombi <- nrow(auxi)
res <- if (ncombi > 676) expand.grid(LETTERS, LETTERS, LETTERS) else expand.grid(LETTERS, LETTERS)
res <- res[do.call(order, res),]
res <- do.call(paste0, res)
auxi$combi <- res[seq_len(ncombi)]

truc2 <- truc2 %>% left_join(auxi, by = "parcelle")
truc2
Source: local data frame [2 x 7]
Groups: Date [?]

        Date seance    parcelle  Surf    Sais oiseaux combi
      <fctr>  <int>       <chr> <dbl>  <fctr>   <int> <chr>
1 2004-10-30      1 279_280_281 41.77 Saison1      55    AA
2 2004-10-30      2     282_283 27.78 Saison1      45    AB
Cordialement,
Maxime

Tomas leon
Messages : 51
Enregistré le : 09 Jan 2018, 16:12

Re: fusionner niveaux d'un facteur en un autre niveau

Messagepar Tomas leon » 16 Fév 2018, 14:06

Bonjour,

Merci à tous pour vos réponses !!

Après avoir utilisé vos scripts je me suis rendu compte qu'il y avait finalement autant de combinaisons que de séances d'observations (soit 1165). Ce qui est assez décevant par rapport à ce que je voulais faire, mais bon... Au moins c'est source d'informations.


Encore merci !


Retourner vers « Questions en cours »

Qui est en ligne

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