2013-05-23 16 views
5

szukam sposób, aby zautomatyzować pewne schematy w badania za pomocą pętli for:Loop poprzez ramki danych i nazw zmiennych

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

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

Wszystkie dataframes mają te same zmienne, tj zm1, VAR2.

Wygląda na to, że pętle nie są najbardziej eleganckim rozwiązaniem, ale nie rozumiem, jak korzystać z funkcji apply dla schematów.

EDIT:

Mój oryginalny przykład stosując mean() nie pomogło w oryginalne pytanie, więc zmieniłem go do funkcji plot.

+2

Stosując 'for' pętli jest w porządku. Po prostu umieść faktyczne dane.frame na liście, a nie tylko ich nazwy w wektorze. Aby być bardziej czytelnym, można również zmienić zawartość pętli na 'plot (var2 ~ var1, data = i)'. Jednak możesz chcieć zapisać wykresy (przeczytaj '? Pdf') lub umieścić kilka wykresów na jednej stronie wykresu (przeczytaj'? Par'). – Roland

+0

Chociaż zgadzam się z Rolandem, że pętle są w porządku, ten przykład z listą data.frame jest naprawdę dobrym rozwiązaniem dla lapply. –

+0

@arumbay Chciałbym również sprawdzić fasetowanie w pakiecie 'ggplot2', aby utworzyć grupy działek. –

Odpowiedz

9

Aby dodatkowo dodać do odpowiedzi Beasterfield, wydaje się jak chcesz zrobić jakąś liczbę złożonych operacji na każdej z ramek danych.

Możliwe jest posiadanie złożonych funkcji w instrukcji stosowania. Więc gdzie masz teraz:

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

To może być tłumaczone na:

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 
}) 

bardziej konkretny przykład stosując działki:

# 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 
}) 

Można również napisać złożonych funkcji, które biorą wiele argumentów :

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 

Mam nadzieję, że to pomoże!

+0

Dziękuję, to było bardzo pomocne i pomogło mi lepiej zrozumieć zasadę działania funkcji! –

6

W odniesieniu do faktycznego pytania należy się dowiedzieć, jak uzyskać dostęp do komórek, wierszy i kolumn data.frame s, matrix s lub list s. Z kodu Chyba chcesz uzyskać dostęp do j „th kolumn data.frame i, więc powinno być:

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

Operator $ mogą być stosowane tylko wtedy, gdy chcesz uzyskać dostęp do konkretnej zmiennej w data.frame, np i$var1. Ponadto jest mniej wydajny niż dostęp przez [, ] lub [[]].

Jednak, mimo że nie jest źle, użycie pętli for nie jest bardzo R'ish. Powinieneś przeczytać o wektoryzowanych funkcjach i rodzinie apply. Więc twój kod może być łatwo zapisane jako:

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

Dzięki - obawiałem się, że mój średni() przykład będzie zbyt prosty. Poszukuję sposobu automatycznego generowania wykresów rozrzutu odnoszących się do zestawu ramek danych (zobacz zmiany w powyższym przykładzie); Sądzę, że jest to również możliwe przy użyciu funkcji stosowania? –

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

Na przykładzie @Roland, chciałem pokazać równoważnik ggplot2. Najpierw musimy zmienić datset trochę:

najpierw oryginalne dane:

> 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 

i umieścić dane w jednym danych.rama z kolumny 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 

i uczynić działkę:

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

enter image description here

Powiązane problemy