2009-11-30 12 views
10

ho chiesto this domanda ieri sulla memorizzazione di un complotto all'interno di un oggetto. Ho provato a implementare il primo approccio (consapevole di non specificare che stavo usando qplot() nella mia domanda originale) e ho notato che non funzionava come previsto.trama Memorizzazione di oggetti in un elenco

library(ggplot2)    # add ggplot2 

string = "C:/example.pdf"  # Setup pdf 
pdf(string,height=6,width=9) 

x_range <- range(1,50)   # Specify Range 

# Create a list to hold the plot objects. 
pltList <- list() 
pltList[] 

for(i in 1 : 16){ 

# Organise data 
y = (1:50) * i * 1000      # Get y col 
x = (1:50)         # get x col 
y = log(y)         # Use natural log 

# Regression 
lm.0 = lm(formula = y ~ x)     # make linear model 
inter = summary(lm.0)$coefficients[1,1]  # Get intercept 
slop = summary(lm.0)$coefficients[2,1]  # Get slope 

# Make plot name 
pltName <- paste('a', i, sep = '') 

# make plot object  
p <- qplot(
    x, y, 
    xlab = "Radius [km]", 
    ylab = "Services [log]", 
    xlim = x_range, 
    main = paste("Sample",i) 
) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)   

print(p)  

pltList[[pltName]] = p  
} 

# close the PDF file 
dev.off() 

ho usato i numeri di esempio in questo caso, in modo che il codice viene eseguito se è appena copiato. Ho passato qualche ora a riflettere su questo, ma non riesco a capire cosa sta andando storto. Scrive il primo set di pdf senza problemi, quindi ho 16 pdf con i grafici corretti.

Poi quando uso questo pezzo di codice:

string = "C:/test_tabloid.pdf" 
pdf(string, height = 11, width = 17) 

grid.newpage() 
pushViewport(viewport(layout = grid.layout(3, 3))) 

vplayout <- function(x, y){viewport(layout.pos.row = x, layout.pos.col = y)} 

counter = 1 

# Page 1 
for (i in 1:3){  
    for (j in 1:3){  
     pltName <- paste('a', counter, sep = '') 
     print(pltList[[pltName]], vp = vplayout(i,j)) 
     counter = counter + 1 
    } 
} 

dev.off() 

il risultato che ottengo è l'ultima linea modello lineare (abline) su ogni grafico, ma i dati non cambia. Quando controllo la mia lista di grafici, sembra che tutti vengano sovrascritti dalla trama più recente (ad eccezione dell'oggetto abline).

Una domanda secondaria meno importante era come generare un pdf di muli-page con diversi grafici su ciascuna pagina, ma l'obiettivo principale del mio codice era archiviare i grafici in un elenco a cui avrei potuto accedere in un secondo momento.

risposta

10

Ok, quindi se il vostro comando trama è cambiato in

p <- qplot(data = data.frame(x = x, y = y), 
      x, y, 
      xlab = "Radius [km]", 
      ylab = "Services [log]", 
      xlim = x_range, 
      ylim = c(0,10), 
      main = paste("Sample",i) 
      ) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)   

poi tutto funziona come previsto. Ecco cosa sospetto stia accadendo (anche se Hadley potrebbe probabilmente chiarire le cose). Quando ggplot2 "salva" i dati, ciò che effettivamente fa è salvare un frame di dati e i nomi dei parametri. Così, per il comando come ho dato, si ottiene

> summary(pltList[["a1"]]) 
data: x, y [50x2] 
mapping: x = x, y = y 
scales: x, y 
faceting: facet_grid(. ~ ., FALSE) 
----------------------------------- 
geom_point: 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL) 

Tuttavia, se non si specifica un parametro data in qplot, tutte le variabili vengono valutati nell'ambito corrente, perché non c'è attaccato (leggere : salvato) cornice dati.

data: [0x0] 
mapping: x = x, y = y 
scales: x, y 
faceting: facet_grid(. ~ ., FALSE) 
----------------------------------- 
geom_point: 
stat_identity: 
position_identity: (width = NULL, height = NULL) 

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL) 

Così, quando la trama è generata la seconda volta, invece di usare i valori originali, utilizza i attuali valori di x e y.

+0

Grazie a RCS e Jonathan, questo ha risolto il problema. Non ero a conoscenza dell'argomento dati e del modo in cui poteva essere utilizzato per archiviare i dati. Sto esaminando quella sezione del libro ora. – womble

1

riguarda la seconda domanda: multi-pagina PDF sono facili - vedi help(pdf):

onefile: logical: if true (the default) allow multiple figures in one 
      file. If false, generate a file with name containing the 
      page number for each page. Defaults to ‘TRUE’. 

Per la vostra domanda principale, non capisco se si desidera memorizzare gli ingressi trama in un elenco per l'elaborazione successiva o le uscite di trama . Se è quest'ultimo, non sono sicuro che plot() restituisca un oggetto che è possibile archiviare e recuperare.

+0

Speravo di memorizzare le uscite di stampa. Se memorizzo gli input di trama, questo include i valori di xey in quel particolare momento? – womble

+0

Naturalmente. Basta memorizzare tutti gli argomenti delle funzioni ecc in un elenco. Questo è molto standard. Ma la tua ipotesi di memorizzare _plot output_ non lo è. I risultati della trama dipendono dal dispositivo e molto probabilmente dal SO. Basta scrivere su un file, possibilmente una bitmap e visualizzarlo. O scrivere app in stile GUI. O basta aprire più finestre di trama. –

+0

Tuttavia, 'ggplot' potrebbe restituirti degli oggetti. In tal caso la risposta di Eduardo è la tua chiave. –

2

C'è un bug nel codice riguardante lista subscripting. Dovrebbe essere

pltList[[pltName]] 

non

pltList[pltName] 

Nota:

class(pltList[1]) 
[1] "list" 

pltList [1] è una listacontenente il primo elemento di pltList.

class(pltList[[1]]) 
[1] "ggplot" 

pltList [[1]] è il primo elemento di pltList.

+0

Scusate - Ho fatto un errore con quello che intendevo incollare. Non ho compreso appieno la differenza tra le sintassi e ho dovuto modificarlo per vedere la differenza. Tuttavia il mio errore esiste ancora come descritto sopra. – womble

1

Un altro suggerimento per quanto riguarda la seconda domanda potrebbe essere quella di utilizzare Sweave o Brew in quanto vi darà il controllo completo su come si visualizza il vostro PDF multipagina.

Date un'occhiata at this related question.

4

Penso che dovresti utilizzare l'argomento data in qplot, ad esempio, memorizzare i vettori in un frame di dati.

Vedere il libro di Hadley, Sezione 4.4:

La limitazione dei dati è semplice: deve essere un frame di dati. Questo è restrittivo e, a differenza di altri pacchetti grafici in R. Lattice, le funzioni possono prendere una cornice dati opzionale o utilizzare i vettori direttamente dall'ambiente globale. ...

I dati vengono memorizzati nell'oggetto di stampa come copia, non come riferimento. Questo ha due importanti conseguenze: se i tuoi dati cambiano, la trama no; e gli oggetti ggplot2 sono interamente autonomi in modo che possano essere salvati() su disco e successivamente caricati() ed stampati senza bisogno di nient'altro da quella sessione.

Problemi correlati