2012-02-03 13 views
9

Ho un frame di dati con un formato simile al seguente:Come posso creare un istogramma da dati aggregati in R?

Month  Frequency 
2007-08  2 
2010-11  5 
2011-01  43 
2011-02  52 
2011-03  31 
2011-04  64 
2011-05  73 

Vorrei creare un istogramma da questi dati, utilizzando contenitori X (X sarà probabilmente circa 15, ma i dati effettivi ha oltre 200 mesi) e utilizzando i dati dalla colonna della frequenza come frequenza per ciascun bin dell'istogramma. Come posso realizzare questo?

Ho provato finora due approcci, con i comandi hist() e barplot(). Il problema con hist() è che non sembra darmi alcun modo di specificare che voglio usare la colonna di frequenza nei calcoli di frequenza per l'istogramma. Il problema con barplot() è che non ho alcuna flessibilità nella scelta dei bin X, e se sono omessi mesi, il grafo risultante non è in realtà un vero istogramma perché l'asse x non è continuo.

L'unica idea che ho adesso è di andare con l'approccio barplot(), riempire i mesi mancanti con un valore di 0 per Frequenza e usare lo spazio = 0 per rimuovere la spaziatura tra le barre. Il problema è che non è particolarmente facile scegliere un numero arbitrario di contenitori.

risposta

4

per ottenere questo tipo di flessibilità, si può avere di replicare i dati. Ecco un modo di farlo con rep:

n <- 10 
dat <- data.frame(
    x = sort(sample(1:50, n)), 
    f = sample(1:100, n)) 
dat 

expdat <- dat[rep(1:n, times=dat$f), "x", drop=FALSE] 

Ora avete il vostro dati replicati nel data.frame expdat, che consente di chiamare hist con un diverso numero di contenitori:

par(mfcol=c(1, 2)) 
hist(expdat$x, breaks=50, col="blue", main="50 bins") 
hist(expdat$x, breaks=5, col="blue", main="5 bins") 
par(mfcol=c(1, 1)) 

enter image description here

+1

Quando ho posto la domanda, l'ho semplificata troppo perché ho trascurato di menzionare che le mie frequenze erano effettivamente comprese tra 1 e 50+ milioni piuttosto che il semplice esempio che ho dato. Queste frequenze erano troppo alte per usare 'rep' sui dati grezzi sulla mia macchina (8 GB di RAM). Ho convertito queste frequenze in una scala più piccola (da 1 a 100.000) che mi ha dato abbastanza di un istogramma (cioè una distribuzione di probabilità) per i miei scopi. Mi piace comunque la tua risposta in generale, e finora è l'unica soluzione che ho trovato che mi dà un istogramma "reale". Grazie! –

+0

Se le tue frequenze sono troppo alte potresti semplicemente scalare il fattore di frequenza in questo modo: expdat <- dat [rep (1: n, times = dat $ f/1000), "x", drop = FALSE] – Marian

4

dare un'occhiata a ggplot2.

se voi dati sono in un data.frame chiamato df:

ggplot(df,aes(x=Month,y=Frequency))+geom_bar(stat='identity') 

o se si vuole tempo continuo:

df$Month<-as.POSIXct(paste(df$Month, '01', sep='-'),format='%Y-%m-%d') 
ggplot(df,aes(x=Month,y=Frequency))+geom_bar(stat='identity') 
+0

Quando provo il secondo esempio, viene visualizzato l'errore "Errore: variabile non continua fornita a scale_y_continua" quando eseguo il comando ggplot. Qualche idea? –

+0

Dovrei sapere di più sui tuoi dati. Presumo che il tuo 'Frequenza' non sia numerico. Se ricrei i tuoi dati: 'df <-data.frame (Month = c ('2007-08', '2010-11', '2011-01', '2011-02', '2011-03', '2011 -04' , '2011-05'), di frequenza = c (2,5,43,52,31,64,73)) '. Traccia bene questi due comandi. Controlla la 'str' dei tuoi dati e assicurati di fornire una variabile continua per y. – Justin

+0

Ho ottenuto il secondo esempio di lavoro convertendo la colonna del mese in un tipo di data. Questo è più vicino a quello che voglio, ma idealmente, avrei meno bidoni. Sembra che questo stia dando una barra (effettivamente un cestino) per ogni singola data._Edit_: ho appena visto il tuo commento sopra; lascia che aggiorni la mia domanda per risolverlo. –

3

Sì, rep soluzioni sprecano troppa memoria nei casi più interessanti/di grandi dimensioni. Il pacchetto CRAN HistogramTools include un'efficiente funzione PreBinnedHistogram che crea un oggetto istogramma di base R direttamente da un elenco di contenitori e interruzioni come la domanda originale fornita.

+0

Grazie, questo è stato davvero utile L'unica delusione è che la funzione prende solo gli argomenti 'break',' counts' e 'xnames', quindi presumibilmente qualsiasi giochino con altre impostazioni deve essere fatto dopo, ad es. 'trama (myhist, axes = FALSE)' piuttosto che impostare 'axes = FALSE' quando l'istogramma è inizialmente costruito. Se qualcuno vuole vedere come appare l'output ho incluso un istogramma prodotto in questo modo in questa risposta: http://stats.stackexchange.com/a/122853/22228 – Silverfish

0

Un'altra possibilità è ridimensionare la variabile di frequenza di un fattore di grandi dimensioni in modo che il rappresentante non abbia tanto lavoro da fare. Quindi regola la scala dell'asse verticale dell'istogramma con lo stesso fattore.

Problemi correlati