Desidero colorare gli sfondi di un diagramma di sfaccettatura ggplot2 in base al valore indicato in una particolare colonna. Usando le risposte alle domande precedenti che ho già chiesto, sono riuscito a mettere insieme ciò di cui avevo bisogno insieme. @ la risposta di joran alla domanda this è stata particolarmente utile in quanto illustra la tecnica di creazione di un frame dati separato da passare a ggplot.Programmazione dei colori con programmazione scale_fill_manual ggplot
Tutto questo funziona bene abbastanza, dando l'output mostrato nell'immagine seguente:
Ecco il codice che ho usato per generare la trama di cui sopra:
# User-defined variables go here
list_of_names <- c('aa','bb','cc','dd','ee','ff')
list_of_regions <- c('europe','north america','europe','asia','asia','japan')
# Libraries
require(ggplot2)
require(reshape)
# Create random data with meaningless column names
set.seed(123)
myrows <- 30
mydf <- data.frame(date = seq(as.Date('2012-01-01'), by = "day", length.out = myrows),
aa = runif(myrows, min=1, max=2),
bb = runif(myrows, min=1, max=2),
cc = runif(myrows, min=1, max=2),
dd = runif(myrows, min=1, max=2),
ee = runif(myrows, min=1, max=2),
ff = runif(myrows, min=1, max=2))
# Transform data frame from wide to long
mydf <- melt(mydf, id = c('date'))
mydf$region <- as.character("unassigned")
# Assign regional label
for (ii in seq_along(mydf$date)) {
for (jj in seq_along(list_of_names)) {
if(as.character(mydf[ii,2]) == list_of_names[jj]) {mydf$region[ii] <- as.character(list_of_regions[jj])}
}
}
# Create data frame to pass to ggplot for facet colours
mysubset <- unique(mydf[,c('variable','region')])
mysubset$value <- median(mydf$value) # a dummy value but one within the range used in the data frame
mysubset$date <- as.Date(mydf$date[1]) # a dummy date within the range used
# ... And plot
p1 <- ggplot(mydf, aes(y = value, x = date, group = variable)) +
geom_rect(data = mysubset, aes(fill = region), xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, alpha = 0.3) +
scale_fill_manual(values = c("japan" = "red", "north america" = "green", "asia" = "orange", "europe" = "blue")) +
geom_line() +
facet_wrap(~ variable, ncol = 2)
print (p1)
Lo script del mondo reale in direzione che sto lavorando è destinato ad essere usato per molti gruppi diversi contenenti molte serie di dati diversi, quindi questo script sarà duplicato molte volte, con solo le variabili che cambiano.
Ciò rende importante che gli elementi definiti dall'utente siano chiaramente accessibili per la modifica, motivo per cui le variabili list_of_names
e list_of_regions
vengono posizionate direttamente all'inizio del file. (Naturalmente, sarebbe meglio non aver bisogno di cambiare lo script, ma piuttosto definire questi elenchi come file esterni o passarli allo script come argomenti.) Ho provato a generalizzare la soluzione usando questi due loop for
per assegnare il regioni. Per un po 'ho cercato di ottenere una soluzione più centrata sull'R utilizzando le funzioni apply
ma non riuscivo a farlo funzionare, così ho rinunciato e bloccato con quello che sapevo.
Tuttavia, nel mio codice così com'è, la chiamata scale_fill_manual
deve essere passata in modo esplicito per definire i colori di riempimento, ad esempio 'europe' = 'blue'
. Queste variabili variano a seconda dei dati che sto elaborando, quindi con lo script nella sua forma attuale, dovrò modificare manualmente la parte ggplot dello script per ciascun gruppo di serie di dati. So che sarebbe molto dispendioso in termini di tempo e ho il forte sospetto che sarebbe anche molto soggetto a errori.
D. Idealmente mi piacerebbe essere in grado di estrarre programmazione e definire i valori richiesti per l'scale_fill_manual
chiamata da una lista precedentemente dichiarato di valori (in questo caso da list_of_regions
) abbinato ad una lista precedentemente dichiarato di colori, ma Non riesco a pensare a un modo per raggiungere questo obiettivo. Hai qualche idea?
E 'possibile se si dispone di un elenco di regione e un elenco di colore. Dov'è la lista dei colori? – kohske
Er, um, non ne ho ancora definito uno! Un elenco di colori arbitrari sarebbe sufficiente per un esempio. – SlowLearner