2013-05-23 16 views
5

Sto cercando un modo per automatizzare alcuni diagrammi in R utilizzando un ciclo for:Loop attraverso il telaio dei dati e nomi di variabili

dflist <- c("dataframe1", "dataframe2", "dataframe3", "dataframe4") 

for (i in dflist) { 
    plot(i$var1, i$var2) 
} 

Tutti dataframes hanno le stesse variabili, vale a dire var1, VAR 2.

Sembra che i loop non siano la soluzione più elegante qui, ma non capisco come utilizzare le funzioni apply per i diagrammi.

EDIT:

Il mio esempio originale utilizzando mean() non ha aiutato nella domanda iniziale, quindi l'ho cambiato a una funzione trama.

+2

Utilizzando una 'ciclo for' è soddisfacente. Basta inserire i dataframes effettivi in ​​un elenco e non solo i loro nomi in un vettore. Per essere più leggibile è possibile anche modificare il contenuto del ciclo in 'plot (var2 ~ var1, data = i)'. Tuttavia, potresti voler salvare i grafici (leggi '? Pdf') o mettere diversi grafici su una pagina del grafico (leggi'? Par'). – Roland

+0

Anche se sono d'accordo con Roland sul fatto che per i loop andrà bene, questo esempio con un elenco di data.frame è davvero adatto per lapply. –

+0

@arumbay Vorrei anche controllare l'aspetto del pacchetto 'ggplot2' per creare gruppi di grafici. –

risposta

9

per aggiungere ulteriore alla risposta di Beasterfield, sembra che si vuole fare un po 'il numero di operazioni complesse su ciascuno dei frame di dati.

È possibile avere funzioni complesse all'interno di un'istruzione apply. Allora, dove ora avete:

for (i in dflist) { 
    # Do some complex things 
} 

Questo può essere tradotto in:

lapply(dflist, function(df) { 
    # Do some complex operations on each data frame, df 
    # More steps 

    # Make sure the last thing is NULL. The last statement within the function will be 
    # returned to lapply, which will try to combine these as a list across all data frames. 
    # You don't actually care about this, you just want to run the function. 
    NULL 
}) 

un esempio più concreto con trama:

# Assuming we have a data frame with our points on the x, and y axes, 
lapply(dflist, function(df) { 
    x2 <- df$x^2 
    log_y <- log(df$y) 
    plot(x,y) 
    NULL 
}) 

è anche possibile scrivere funzioni complesse che tengono più argomenti :

lapply(dflist, function(df, arg1, arg2) { 
    # Do something on each data.frame, df 
    # arg1 == 1, arg2 == 2 (see next line) 
}, 1, 2) # extra arguments are passed in here 

Spero che questo ti aiuti!

+0

Grazie, è stato molto utile e mi ha aiutato a comprendere meglio il principio alla base delle funzioni di applicazione! –

6

Per quanto riguarda la tua domanda attuale, dovresti imparare come accedere a celle, righe e colonne di data.frame s, matrix s o list s. Dal codice Credo che si desidera accedere al j 'th colonne del data.frame i, quindi si dovrebbe leggere:

mean(i[,j]) 
# or 
mean(i[[ j ]]) 

L'operatore $ può essere utilizzato solo se si desidera accedere a una variabile particolare nella vostra data.frame, es i$var1. Inoltre, è meno performante rispetto all'accesso da [, ] o [[]].

Tuttavia, anche se non è errato, l'utilizzo dei loop for non è molto R'ish. Dovresti leggere le funzioni vettoriali e la famiglia apply. Così il vostro codice potrebbe facilmente essere riscritta come:

set.seed(42) 
dflist <- vector("list", 5) 
for(i in 1:5){ 
    dflist[[i]] <- data.frame(A = rnorm(100), B = rnorm(100), C = rnorm(100)) 
} 
varlist <- c("A", "B") 

lapply(dflist, function(x){ colMeans(x[varlist]) }) 
+0

Grazie - temevo che il mio esempio medio() fosse troppo semplice. Sto cercando un modo per generare automaticamente grafici a dispersione riferiti a un insieme di frame di dati (vedi le modifiche nell'esempio sopra); Immagino che questo sia possibile anche usando le funzioni apply? –

1
set.seed(42) 
dflist <- list(data.frame(x=runif(10),y=rnorm(10)), 
       data.frame(x=rnorm(10),y=runif(10))) 

par(mfrow=c(1,2)) 
for (i in dflist) { 
    plot(y~x, data=i) 
} 
2

Utilizzando l'esempio di @Roland, volevo mostrare l'equivalente ggplot2. Per prima cosa dobbiamo cambiare il Set di dati un po ':

Prima i dati originari:

> dflist 
[[1]] 
      x   y 
1 0.9148060 -0.10612452 
2 0.9370754 1.51152200 
3 0.2861395 -0.09465904 
4 0.8304476 2.01842371 
5 0.6417455 -0.06271410 
6 0.5190959 1.30486965 
7 0.7365883 2.28664539 
8 0.1346666 -1.38886070 
9 0.6569923 -0.27878877 
10 0.7050648 -0.13332134 

[[2]] 
      x   y 
1 0.6359504 0.33342721 
2 -0.2842529 0.34674825 
3 -2.6564554 0.39848541 
4 -2.4404669 0.78469278 
5 1.3201133 0.03893649 
6 -0.3066386 0.74879539 
7 -1.7813084 0.67727683 
8 -0.1719174 0.17126433 
9 1.2146747 0.26108796 
10 1.8951935 0.51441293 

e mettere i dati in uno dei dati.cornice, con una colonna id

require(reshape2) 
one_df = melt(dflist, id.vars = c("x","y")) 
> one_df 
      x   y L1 
1 0.9148060 -0.10612452 1 
2 0.9370754 1.51152200 1 
3 0.2861395 -0.09465904 1 
4 0.8304476 2.01842371 1 
5 0.6417455 -0.06271410 1 
6 0.5190959 1.30486965 1 
7 0.7365883 2.28664539 1 
8 0.1346666 -1.38886070 1 
9 0.6569923 -0.27878877 1 
10 0.7050648 -0.13332134 1 
11 0.6359504 0.33342721 2 
12 -0.2842529 0.34674825 2 
13 -2.6564554 0.39848541 2 
14 -2.4404669 0.78469278 2 
15 1.3201133 0.03893649 2 
16 -0.3066386 0.74879539 2 
17 -1.7813084 0.67727683 2 
18 -0.1719174 0.17126433 2 
19 1.2146747 0.26108796 2 
20 1.8951935 0.51441293 2 

e rendere il terreno:

require(ggplot2) 
ggplot(one_df, aes(x = x, y = y)) + geom_point() + facet_wrap(~ L1) 

enter image description here

Problemi correlati