it-swarm.com.de

Schleife durch Datenrahmen und Variablennamen

Ich suche nach einer Möglichkeit, einige Diagramme in R mithilfe einer FOR-Schleife zu automatisieren:

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

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

Alle Datenrahmen haben die gleichen Variablen, d. H. Var1, var2. 

Es scheint, dass for-Schleifen hier nicht die eleganteste Lösung sind, aber ich verstehe nicht, wie die apply-Funktionen für Diagramme verwendet werden.

BEARBEITEN:

Mein ursprüngliches Beispiel mit mean() hat in der ursprünglichen Frage nicht geholfen, also habe ich es in eine Plot-Funktion geändert.

5
Timm S.

Um Beasterfields Antwort noch weiter zu ergänzen, scheint es, als wollten Sie einige komplexe Operationen für jeden der Datenrahmen ausführen.

Innerhalb einer Apply-Anweisung können komplexe Funktionen vorhanden sein. Wo hast du jetzt:

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

Dies kann übersetzt werden 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
})

Ein konkreteres Beispiel mit Plot:

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

Sie können auch komplexe Funktionen schreiben, die mehrere Argumente benötigen:

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

Hoffe das hilft dir aus!

10
Scott Ritchie

In Bezug auf Ihre eigentliche Frage sollten Sie lernen, wie Sie auf Zellen, Zeilen und Spalten von data.frames, matrixs oder lists zugreifen. Ich denke, Sie möchten von Ihrem Code aus auf die j'ten Spalten des data.frame i zugreifen, so dass es lesen sollte:

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

Der $-Operator kann nur verwendet werden, wenn Sie auf eine bestimmte Variable in Ihrem data.frame zugreifen möchten, z. i$var1. Außerdem ist es weniger performant als der Zugriff mit [, ] oder [[]].

Obwohl dies nicht falsch ist, ist die Verwendung von for-Schleifen nicht sehr gut. Sie sollten über vektorisierte Funktionen und die apply-Familie lesen. So könnte Ihr Code leicht umgeschrieben werden als:

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]) } )
6
Beasterfield

Am Beispiel von @Roland wollte ich Ihnen das Äquivalent von ggplot2 zeigen. Zuerst müssen wir das Datset ein wenig ändern:

Zuerst die Originaldaten:

> 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

und legen Sie die Daten in einem data.frame mit einer id-Spalte ab

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

und mache die Handlung:

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

enter image description here

2
Paul Hiemstra
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)
}
1
Roland

Basierend auf der Lösung von Scott Ritchi wäre dies das reproduzierbare Beispiel, das auch die Rückmeldung vor lapply verbirgt:

# split dataframe by condition on cars hp
f <- function() trunc(signif(mtcars$hp, 2) / 100)
dflist <- lapply(unique(f()), function(x) subset(mtcars, f() == x ))

Dadurch wird das mtcars-Datenframe in Teilmengen unterteilt, die auf der Variablenvariable hp basieren (0 für hp unter 100, 1 für die 100er, 2 für 200er usw.).

Und plott es:

# use invisible to prevent the feedback message from lapply
invisible(
    lapply(dflist, function(df) {
    x2 <- df$mpg^2
    log_y <- log(df$hp)
    plot(x2, log_y)
    NULL
}))

invisible() verhindert die lapply()-Nachricht:

16 
9 
6 
1 
[[1]]
NULL

[[2]]
NULL

[[3]]
NULL

[[4]]
NULL

 enter image description here

0
f0nzie