Home Forum Statistica con R Grafico per rappresentare la relazione tra numerica e categoriale

This topic contains 11 replies and has 2 voices.

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #4702

    Alar
    Participant

    Ciao ragazzi, come da titolo sto cercando un grafico che mi permetta in maniera intuitiva di rappresentare la relazione esistente tra una variabile numerica e una categoriale.
    Mi spiego meglio riportandovi l’esempio pratico: nel mio dataset ho una variabile “età” e una variabile “email” (quest’ultima presenta i due classici livelli Y/N, quindi indica il possesso o meno di un’email da parte dei clienti intervistati). Dall’analisi del dataset ho capito che – come giusto aspettarsi – la probabilità che i clienti più giovani hanno l’email è più alta di quella dei clienti più anziani, quindi i giovani hanno in media l’email, mentre più si va avanti con gli anni più è bassa la probabilità che il cliente possieda l’email.
    La domanda è la seguente: mi sapreste indicare un grafico immediato e intuitivo che possa rappresentare questa situazione? Perché grafici come mosaicplot, plot, pairs, etc. non sono d’aiuto. Credo comunque che debba servirmi della tabelle delle frequenze a doppia entrata.

    In attesa di un vostro suggerimento, saluti a tutti

    #4703

    Ciao Alar,
    probabilmente qualcuno ti consiglierà qualcosa di molto più efficace ed elegante, ma pensi che possa essere d’aiuto un Sunflowerplot? In cui a differenza dello scatterplot i valori ripetuti di “y” vengono riportati come numero di petali rossi. In questo molto si potrebbe riuscire a notare una maggiore concentrazione di giovani che hanno l’email come nel seguente esempio.

    
    eta <- c(20, 20, 20, 32, 21, 22, 23, 43, 55, 66, 88, 99)
    email <- factor(c("si", "si","si", "si", "no", "si", "no", "no", "no", "no", "no", "no"))
    sunflowerplot(email~eta, ylim=c(0,3), axes=F, xlab = "Età", ylab = "Email")
    title("Sunflowerplot")
    axis(2, 1:2, c("no", "si"))
    axis(1, seq(0, 100, 20), seq(0, 100, 20))
    

    Sunflowerplot

    #4704

    Alar
    Participant

    Ciao Francesco,
    ti ringrazio per la soluzione, che reputo più che valida, ma applicandola al mio caso non dà l’effetto che vorrei dare al lavoro, questione di gusti insomma. Ho comunque trovato un’altra soluzione grafica, che reputo abbastanza convincente.
    Attraverso il famoso pacchetto ggplot2 ho utilizzato la funzione ggplot in questo modo:

    ggplot(dataset, aes(x = age, fill = email)) + geom_bar() + xlab(label=”Età”) + ylab(label=”Frequenze assolute”) + ggtitle(label = “Relazione tra Età e Email”)

    e il risultato è comunque abbastanza intuitivo e poi graficamente è come avrei voluto che fosse. Comunque ti ringrazio lo stesso, penso che potrà tornarmi utile questo tipo di grafico.

    In realtà adesso ho un altro quesito, molto simile a questo. Vorrei sempre indagare la relazione tra una variabile categoriale e una numerica; mi spiego con il dataset.
    Ho la variabile sesso (M/F) e la variabile numerica Canone (sono tre diversi canoni che i clienti possono pagare, l’uno esclude l’altro). Vorrei capire in media qual è il canone più utilizzato dalle donne e quale quello più utilizzato dagli uomo e potrei arrivare alla soluzione attraverso una distribuzione di frequenze relative a doppia entrata, con il comando prop.table(table(dataset$gender,dataset$fee.paid)), ma io vorrei anche dare una rappresentazione grafica di questa tabella e non so che funzione utilizzare.

    Hai idee al riguardo? Qualcuno ha qualche consiglio da darmi?
    Grazie ancora per l’attenzione, un saluto

    #4705

    Ciao Alar, in effetti la soluzione che hai trovato è più intuitiva, senza contare il fatto che ggplot2 rende i grafici esteticamente più accattivanti.

    Per la tua seconda domanda, forse non ho capito. Se dici che la variabile “canone” ha tra livelli, non è categoriale pure questa?
    Se così fosse, usando la stessa funzione che hai usato precedentemente, servendoti dell’argomento fill e aggiungendo un geom_bar, ti vengono mostrate le proporzioni fra le due variabili.

    
    fee <- factor(c(rep("a", 6), rep("b", 6), rep("c", 8)))
    gender <- factor(c(rep("m", 10), rep("f", 10)))
    dataset <- data.frame(gender, fee)
    
    prop.table(table(gender, fee))
          fee
    gender   a   b   c
         f 0.0 0.1 0.4
         m 0.3 0.2 0.0
    
    ggplot(dataset, aes(x = gender, fill = fee)) + 
      geom_bar() +
      xlab(label="genere") + ylab(label="Frequenze relative") + 
      ggtitle(label = "Proporzione di fee per genere")
    

    proporzioni di una variabile per i livelli di un'altra

    #4706

    Alar
    Participant

    La variabile Canone (fee.paid) è numerica perché i valori in essa espressi – nonostante siano soltanto tre – sono espressi numericamente e per l’esattezza sono 50, 125 e 400. Anche quando ho costruito il dataset in R ho fatto in modo che questa fosse a tutti gli effetti una variabile numerica, nonostante come fai notare tu può essere facilmente vista come una variabile categoriale a tre livelli (a,b,c).

    Penso sia questo il problema, ossia il fatto che agli occhi di R non sia vista come una variabile categoriale, come un factor (se non sbaglio è così che si dice?) e perciò quando vado a ricopiare il tuo comando in console mi esce un bruttissimo grafico in cui ho due enormi istogrammi di colore grigio che non mi dicono nulla sui livelli.

    Credi si possa rimediare al problema? ad esempio trasformando momentaneamente la mia variabile Canone in una categoriale a tre livelli? Perché il grafico che mi proponi tu è perfetto!

    #4707

    Si penso che possa trattare la tua variabile numerica come fattore in modo che venga rappresentata graficamente nel modo che ti ho proposto.
    Forse potresti aggiungere al tuo dataset una variabile in più (e.g. “canone_fac”), che non è altro che la tua variabile numerica ricodificata come fattore, e successivamente utilizzare questa per produrre il grafico.

    
    fee <- c(rep(50, 6), rep(125, 6), rep(400, 8))
    gender <- factor(c(rep("m", 10), rep("f", 10)))
    dataset <- data.frame(gender, fee)
    
    prop.table(table(gender, fee))
          fee
    gender  50 125 400
         f 0.0 0.1 0.4
         m 0.3 0.2 0.0
    
    dataset$fee_fac <- factor(dataset$fee)
    
    
    ggplot(dataset, aes(x = gender, fill = fee_fac)) + 
      geom_bar() +
      xlab(label="genere") + ylab(label="Frequenze relative") + 
      ggtitle(label = "Proporzione di fee per genere")
    

    proporzioni di una variabile per i livelli di un altra

    #4708

    Alar
    Participant

    Tutto perfetto, mi trovo con quello che dici ed a dire la verità ero giunto al tuo stesso risultato, ma con il comando as.factor.

    C’è solo un unico problema cui non riesco a dare una soluzione, sia che rappresenti il grafico con i miei comandi sia che lo faccia con quelli che mi hai appena proposto. Nel grafico, l’asse delle y non misura le frequenze relative e credo neanche quelle assolute; credo misuri i valori grezzi del dataset: il mio dataset è composto da 149 donne e quindi l’altezza dell’istogramma del genere “F” arriva a 149 e non a 10 (=100%) come il tuo.

    Sapresti rispondere a questa mia ultima richiesta d’aiuto?

    In più, sai con ggplot come si cambiano i colori delle sezioni degli istogrammi?
    Grazie ancora

    #4709

    Molto strano! Potresti postarmi l’output del comando str(dataset) per mostrarmi la struttura delle tue variabili?

    e poi potresti mostrarmi anche i comandi che stai eseguendo per arrivare a produrre il grafico?

    Per quanto riguarda i colori aggiungi semplicemente questo al tuo ggplot:

    
    + scale_fill_manual(values = c("black", "green", "blue"))
    
    #4710

    Alar
    Participant

    Il comando struttura del mio dataset riporta questo

    'data.frame':	450 obs. of  14 variables:
     $ customer.id                         : int  1 2 3 4 5 6 7 8 9 10 ...
     $ age                                 : int  24 18 22 25 57 23 55 19 32 38 ...
     $ gender                              : Factor w/ 2 levels "F","M": 2 1 2 2 2 1 1 2 2 1 ...
     $ email                               : Factor w/ 2 levels "N","Y": 2 2 1 2 1 2 1 2 2 1 ...
     $ ad.promotion                        : Factor w/ 2 levels "N","Y": 2 1 1 2 1 1 1 1 1 1 ...
     $ annual.disposable.income            : int  22354 20587 12369 17526 42567 12544 35698 13589 25641 37611 ...
     $ fee.paid                            : int  50 50 50 125 125 50 125 50 125 50 ...
     $ avarage.extra.charges               : int  16 11 12 11 43 0 25 13 26 24 ...
     $ distance.to.gym                     : num  0.6 5.4 3.5 5.7 6.7 4 4 4.2 7 2.5 ...
     $ avarage.weekly.frequency            : int  3 3 4 3 3 2 3 4 3 3 ...
     $ satisfaction.of.the.cleaning        : int  5 4 4 3 5 2 4 4 4 3 ...
     $ satisfaction.of.the.physical.results: int  4 2 5 4 4 1 2 5 4 4 ...
     $ satisfaction.of.the.hospitality     : int  4 2 5 4 1 4 3 5 3 3 ...
     $ overall.satisfaction                : num  4.3 2.6 4.7 3.7 3.7 1.9 2.8 4.7 3.8 3.5 ...

    e i comandi utilizzati per produrre il grafico sono i seguenti:

    Canone <- as.factor(gym.df$fee.paid)
    ggplot(gym.df, aes(x = gender, fill = Canone)) + geom_bar() + xlab(label="genere") + ylab(label="Frequenze relative") + ggtitle(label = "Proporzione del canone per genere")

    Grazie per la dritta sui colori!

    #4711

    Penso di aver capito! Anche il mio esempio sembrava mostrare le frequenze relative, ma in realtà stava mostrando i valori grezzi (questo perché per puro caso ho deciso di assegnare sia ai maschi che alle femmine numerosità 10 :/).
    Per ottenere le frequenze relative prova così e dimmi se funziona:

    
    Canone <- as.factor(gym.df$fee.paid)
    ggplot(gym.df, aes(x = gender, fill = Canone)) + 
    geom_bar(position = "fill") + xlab(label="genere") + 
    ylab(label="Frequenze relative") + 
    ggtitle(label = "Proporzione del canone per genere")
    

    se vuoi che le frequenze siano espresse in percentuale puoi anche fare così:

    
    library(scales)
    Canone <- as.factor(gym.df$fee.paid)
    ggplot(gym.df, aes(x = gender, fill = Canone)) + 
    geom_bar(position = "fill") + 
    xlab(label="genere") + 
    ylab(label="Frequenze relative") + 
    ggtitle(label = "Proporzione del canone per genere") +
    scale_y_continuous(labels = percent_format())
    
    #4713

    Alar
    Participant

    Ti ringrazio tantissimo Francesco,
    entrambe le soluzioni rispondono perfettamente alle mie esigenze. Grazie ancora!

    #4717

    Alar
    Participant

    Scusami ancora Francesco, ma avrei un’altra richiesta da porti, se è possibile.
    Nel mio dataset ci sono anche delle variabili che esprimono il livello di soddisfazione dei clienti in merito a determinati ambiti, ad esempio la pulizia degli ambienti, l’accoglienza del personale, etc.
    A me piacerebbe costruire un grafico che metta in relazione l’età con – ad esempio – il livello di soddisfazione della pulizia, per capire se i clienti più giovani assegnano livelli di soddisfazione più alti o più bassi (e così via per altre “categorie” di età).

    Come detto prima, è possibile utilizzare il comando ggplot in questo modo:

    Pulizia <- as.factor(gym.df$satisfaction.of.the.cleaning)
    > str(SoddPulizia.levels)
     Factor w/ 5 levels "1","2","3","4",..: 5 4 4 3 5 2 4 4 4 3 ...
    ggplot(gym.df, aes(x = age, fill = Pulizia)) + geom_bar(position = "fill") 
    + xlab(label="Età") + ylab(label="Frequenze relative") 
    + ggtitle(label = "Relazione tra Età e Soddisfazione della pulizia") 
    + scale_y_continuous(labels = percent_format())

    ma reputo il grafico molto confusionario e poco immediato, per la presenza dei troppi istogrammi che riflettono la numerosità della variabile età.
    Si potrebbe ovviare a questo?

    Ad esempio, si potrebbero creare degli intervalli di età del tipo 18-24, 25-30, 31-35, 36-40, 41-50, 51-65(max) e riportare questi sull’asse delle ascisse, mettendoli in relazione con i livelli di soddisfazione? Naturalmente gli istogrammi dovrebbero riportare poi delle “medie” dei valori di soddisfazione, però in questo modo avrei soltanto 6 istogrammi e sarebbe molto più intuitivo.

    Grazie per la pazienza

    • This reply was modified 7 months ago by  Alar.
Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.