2012-05-09 19 views
12

Ho bisogno per creare un semplice diagramma linea con gruppi utilizzando i seguenti dati:Come creare un grafico a linee con gruppi in Base R senza loop?

test = data.frame(x = rep(1:3, each = 2), 
        group = rep(c("Group 1","Group 2"),3), 
        groupcd= rep(c(1,2),3), 
        y= c(22,8,11,4,7,5) 
       ) 

posso facilmente farlo con GGPLOT:

library(ggplot2) 
    #GGPLOT 
    qplot(x=x, y=y, 
      data=test, 
      colour=group, 
      main="GGPLOT line plot with groups") + 
     geom_line() 

enter image description here

posso anche farlo con TRELLIS:

library(lattice) 
xyplot(y~x, 
     type="b", 
     group=group, 
     data=test, 
     main="TRELLIS line plot with groups", 
     auto.key =list(
     lines = TRUE) 
     ) 

enter image description here

Tuttavia, sono un po 'riluttante a utilizzare GGPLOT o TRELLIS adesso. Mi piacerebbe essere in grado di creare questo grafico con base R. L'unico modo che posso ottenere questa trama di lavorare in base R è quello di utilizzare per il ciclo:

# set up empty plot 
plot(test$y ~test$x, ylab="y", xlab="x", type="n", main="Base R line plot with groups") 
colors<-c("red","blue") 
#plot each group in the for loop 
number_of_groups <- as.numeric(max(unique(test$groupcd))) #calculate number of groups 
for (i in 1:number_of_groups) 
{ 
    temp <- subset(test, groupcd==i) 
    lines(temp$x, temp$y, col=colors[i]) 
    points(temp$x, temp$y, col=colors[i]) 
} 
legend("top", legend=unique(test$group), text.col =colors ) 

enter image description here

Questo approccio sembra abbastanza contorto. C'è un modo più semplice per farlo nella base R? Esiste un'opzione di gruppo nella funzione di trama R di base? Grazie mille.

+4

trasforma i tuoi dati in grande formato e usa 'matplot' ... –

+0

Grazie mille! Non ero nemmeno a conoscenza di matplot - questo è estremamente utile. È un'ottima soluzione e sembra essere l'opzione migliore finora. Sono semplicemente un gruppo molto sorpreso che non può essere fatto facilmente con PLOT. Grazie ancora –

+0

Penso che dovresti inviare la tua soluzione 'matplot' come risposta piuttosto che come una modifica alla tua domanda (anche se a seconda della tua reputazione potresti dover aspettare un po '- non lo so). Penso di poter dire con sicurezza che non esiste * non * una semplice opzione di gruppo in 'base :: plot'.Un paio di altri pensieri sul tuo codice qui sopra: (1) Penso che tu possa usare 'sottoinsieme (test_transposed, select = -x)' per eliminare la colonna 'x'; (2) probabilmente vuoi 'lty = 1: 2, col = colors, pch = 1: 2' nella tua istruzione' legend'. –

risposta

8

Che dire qualcosa di simile come base su cui lavorare:

test = data.frame(x = rep(1:3, each = 2), 
        group = rep(c("Group 1","Group 2"),3), 
        groupcd= rep(c(1,2),3), 
        y= c(22,8,11,4,7,5) 
       ) 

xvals <- split(test$x,test$group) 
yvals <- split(test$y,test$group) 

plot(1:max(unlist(xvals)),ylim=(c(0,max(unlist(yvals)))),type="n") 
# thanks to @BenBolker for refining this next key line 
mapply(lines,xvals,yvals,col=c("red","blue"),pch=1:2,type="o") 

Risultato:

enter image description here

+0

Questo è un approccio brillante. Tuttavia, non è ancora una variazione dell'approccio loop? cioè non esiste una variabile di "raggruppamento", come quella con la trama di TRELLIS. Stavo per inviare la soluzione matplot come risposta. Sono failry nuovo in R per decidere quale approccio è migliore. –

+0

Grazie, ma potrebbe essere un elogio prematuro. Non so come passare un vettore di colori all'interno dell'istruzione 'mapply' in modo che ogni riga non abbia lo stesso aspetto. Deve essere possibile, ma potrebbe rendere di nuovo complessa questa soluzione 'semplice'. – thelatemail

+0

È una soluzione piuttosto estensibile, ad es. 'mapply (linee, xvals, yvals, col = c (" rosso "," blu "), lty = 1: 2, pch = 1: 2, MoreArgs = list (type =" b "))' - tutto il gli argomenti vengono vettorizzati * tranne * quelli in 'MoreArgs' –

2

approccio diverso utilizzando MATPLOT:

library(reshape) 
test = data.frame(x = rep(1:3, each = 2), 
        group = rep(c("Group 1","Group 2"),3), 
        groupcd= rep(c(1,2),3), 
        y= c(22,8,11,4,7,5) 
       ) 
colors<-c("red","blue") 

#Transform data to wide format 
test_transposed<-reshape(test, 
         idvar='x', 
         drop="group", 
         timevar="groupcd", 
         direction="wide") 
colors<-c("red","blue") 

#drop x column 
test_transposed$x<-NULL 

matplot(test_transposed, 
     type = "b", 
     ylab="y", 
     col=colors, 
     main="MATPLOT with groups", 
     pch = 1:2) 

legend("top", 
     legend=unique(test$group), 
     lty=1:2, 
     col=colors, 
     pch=1:2 ) 

enter image description here

1

Mi stavo chiedendo anche questo. I miei dati panel non hanno una copertura completa sull'asse x (anni), quindi soluzioni a matrice potrebbero diventare complicate. Invece, sono andato con ...

mytest = data.frame(
       x = rep(1:3, each = 2), 
       groupcd= rep(c(1,2),3), 
       y= c(22,8,11,4,7,5) 
      ) 
mytest = rbind(mytest,c(2,3,15),c(3,3,17)) 

plottables <- split(mytest,mytest$groupcd) 
plot(y~x,dat=plottables[[1]],type="l",xlim=range(mytest$x),ylim=range(mytest$y)) 
lapply(plottables,function(z)points(y~x,dat=z,type="l")) 
0

vorrei estendere un po 'questo post..suppose che instad di tracciare righe voglio linee di regressione. Estendere il codice di @Frank ..

mytest = data.frame(
       x = rep(1:3, each = 2), 
       groupcd= rep(c(1,2),3), 
       y= c(22,8,11,4,7,5) 
      ) 
mytest = rbind(mytest,c(2,3,15),c(3,3,17)) 

    plottables <- split(mytest,mytest$groupcd) 
plot(y~x,dat=plottables[[1]],type="n",xlim=range(mytest$x),ylim=range(mytest$y)) 
lapply(plottables,function(z)points(z$x, z$y)) 
lapply(plottables,function(z)lines(z$x, predict(lm(z$y ~ z$x), list(z$x)))) 

Ora supponiamo voglio anche i colori per cambiare per ogni livello di gruppo. Ho provato l'approccio suggerito dal @BenBolker

xvals <- tapply(mytest$x, mytest$groupcd, function(x) return(x)) 
    yvals <- tapply(mytest$y, mytest$groupcd, function(x) return(x)) 

    plot(1:max(unlist(xvals)),ylim=(c(0,max(unlist(yvals)))),type="n") 
    mapply(points, xvals, yvals, bg=c(1:3),pch=21,type="p") 
    mapply(lines(xvals, predict(lm(yvals ~ xvals), list(xvals)), col = c(1:3))) 

ma des non lavoro.

Problemi correlati