histogramme nombre de valeur unique par classe d'une variable

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

Mathieu Lagarde
Messages : 14
Enregistré le : 19 Mar 2010, 09:28

histogramme nombre de valeur unique par classe d'une variable

Messagepar Mathieu Lagarde » 29 Aoû 2019, 15:44

Bonjour,
Je galère depuis quelques temps sur un problème qui me parassait simple à la base...
Tout d'abord, mon fichier de données simplifié:

Code : Tout sélectionner

   id TAXO altitude
1   1  sp1       54
2   2  sp2       NA
3   3  sp1      256
4   4  sp1        2
5   5  sp3       NA
6   6  sp4       30
7   7  sp4       59
8   8  sp2      312
9   9  sp4      756
10 10  sp4       18



Voici la sortie de dput()

Code : Tout sélectionner

structure(list(id = 1:10, TAXO = structure(c(1L, 2L, 1L, 1L,
3L, 4L, 4L, 2L, 4L, 4L), .Label = c("sp1", "sp2", "sp3", "sp4"
), class = "factor"), altitude = c(54L, NA, 256L, 2L, NA, 30L,
59L, 312L, 756L, 18L)), class = "data.frame", row.names = c(NA,
-10L))


De ce fichier, j'ai obtenu un certain nombre de graphes: histogramme du nombre de données par classe d'altitude pour toutes les données et pour chaque espèce (TAXO).

Ex:

Code : Tout sélectionner

library(ggplot2)
library(grid)
library(tidyverse)

dim_df <- as.factor(dim(data[!is.na(data$altitude),])[1])

p_alt <- ggplot(data, aes(altitude, fill= ..x..)) + geom_histogram(breaks = seq(0,3000, by=100), show.legend = FALSE) + scale_fill_gradientn(colors = terrain.colors(30)) + coord_flip() + xlab("altitude") + ylab("nombre d’observations") + theme(axis.title.x = element_text(size=16),axis.text.x = element_text(size = 14),axis.title.y = element_text(size=16),axis.text.y = element_text(size = 14), panel.grid.minor.x=element_blank(),panel.grid.major.x=element_blank())+ annotation_custom(grobTree(textGrob(label= paste("n =", dim_df, sep=" "), x=0.84, y=0.95, hjust=0, vjust= 0, gp=gpar(fontsize=15))))
print(p_alt)


Maintenant, je bloque sur le dernier graphe que je souhaite produire: histogramme du nombre d'espèces par classe d'altitude.

Au mieux, j'ai obtenu ce plot:

Code : Tout sélectionner

#filtre des données pour altitude != NA
df2 <- dplyr::filter(data, !is.na(altitude))
#discrétisation de la variable "altitude" par pas de 100m
df2$alt_class<-cut(df2$altitude, seq(0,3000, by=100))

#nombre de valeur unique par classe d'altitude
species_counts <- df2 %>%
  group_by(df2$alt_class) %>%
  summarise(species_number = n_distinct(TAXO))

dfsc<-as.data.frame(species_counts)
plot(dfsc)


Certes, j'obtiens une représentation graphique du résultat souhaité. Mais j'aimerais représenter les résultats sous le même format que l'exemple précédent...

Autre méthode essayée:

Code : Tout sélectionner

dfsc2 <- data.frame(altitude=unique(df2$alt_class), RichTax=sapply(unique(df2$alt_class), function(x){length(unique(df2$TAXO[df2$alt_class==x]))}))


Mais je me retrouve bloqué au même stade...

Le data frame obtenu (dfsc) est celui que je veux représenter sous forme d'un histogramme (geom_histogram), comme j'ai pu le faire pour les graphes précédents.

Mais là, je sèche complètement.
Auriez-vous une piste à exploiter svp?

Merci ! :)

Mat'

Guillaume Devailly
Messages : 28
Enregistré le : 22 Déc 2017, 12:31

Re: histogramme nombre de valeur unique par classe d'une variable

Messagepar Guillaume Devailly » 03 Sep 2019, 07:08

Si j'ai bien compris la question, je propose quelque chose comme cela:

Code : Tout sélectionner

ggplot(dfsc, aes(x = `df2$alt_class`, y = species_number, fill = ..x..)) +
    geom_col() +
    scale_fill_gradientn(colors = terrain.colors(30)) +
    xlab("altitude") +
    ylab("nombre d’observations")

Mathieu Lagarde
Messages : 14
Enregistré le : 19 Mar 2010, 09:28

Re: histogramme nombre de valeur unique par classe d'une variable

Messagepar Mathieu Lagarde » 03 Sep 2019, 14:44

Bonjour Guillaume,
Merci beaucoup. C'est effectivement le rendu que je cherchais à obtenir... Mais... la construction du geom_col semble différente de celle du geom_histogram, et je n'arrive pas à manipuler cet objet.
- j'ai des données manquantes que je n'arrive pas à supprimer. (Elles sont pourtant filtrées lors de la création de mon objet df2 !!!)
- mes classes d'altitude s'enchainent dans le bon ordre, mais une classe ne contient aucune donnée et n'apparaît pas sur le graphique.
- j'aurais souhaité obtenir un résultat proche de celui-ci, avec l'axe des altitudes représenté de cette façon, pour plus d'homogénéité...

Résultat obtenu:
https://imgur.com/gVEEgo3

Résultat souhaité:
https://imgur.com/cDoKsep

Quels sont les arguments qui me permettraient d'obtenir le résultat souhaité?

Autre question. Je ne comprends pas la notation utilisée à cet endroit:
Guillaume Devailly a écrit :

Code : Tout sélectionner

ggplot(dfsc, aes(x = [b]`df2$alt_class`[/b], y = species_number, fill = ..x..))

Pourquoi n'est-il pas posible d'appeler df2$alt_class de la même façon que species_number ? ça m'échappe complètement là...

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

Re: histogramme nombre de valeur unique par classe d'une variable

Messagepar Gabriel Terraz » 03 Sep 2019, 16:55

Bonjour,
Je propose cette solution, sans package supplémentaire.

Un jeu de données bidon :

Code : Tout sélectionner

sp <- paste0("sp",1:40)
df <- data.frame(TAXO = sample(sp, 1000, rep = T), altitude = rbeta(1000,1.5,3.5) * 3000)
df$altitude[sample(1000,15)] <- NA ## Gestion des données manquantes ?


Code : Tout sélectionner

df$alt_class <- cut(df$altitude, seq(0,3000, by = 100))
tap <- tapply(df$TAXO, df$alt_class, function(i) length(unique(i)))
barplot(tap, beside = T, horiz = T, axes = F, names = F, xlim = c(0,45), space = 0, border = NA, col = terrain.colors(30))
axis(1, at = seq(0,40,10), labels = seq(0,40,10))
axis(2, at = c(0,10,20,30), labels = c(0,1000,2000,3000), las = 1)

Mathieu Lagarde
Messages : 14
Enregistré le : 19 Mar 2010, 09:28

Re: histogramme nombre de valeur unique par classe d'une variable

Messagepar Mathieu Lagarde » 10 Sep 2019, 10:58

Bonjour,
Merci beaucoup. C'est parfait pour ce que je souhaitais obtenir.
Bonne journée,
Mat'


Retourner vers « Questions en cours »

Qui est en ligne

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