wake-up-neo.com

Mehrere Darstellungen mit Schleifen in R

Ich versuche immer noch, meinen Kopf herumzureißen und dabei Schleifen zu verwenden, um in R zu plotten. Ich möchte die Darstellung der Spalten z_1 gegen z_2 im Datenrahmen unten (entsprechend den verschiedenen Namen in Spalte x_1) machen.

x_1 <- c("A1", "A1","A1", "B10", "B10", "B10","B10", "C100", "C100", "C100")


z_1 <- rnorm(10, 70) 

z_2 <- rnorm(10, 1.7)

A <- data.frame(x_1, z_1, z_2)

Als solches möchte ich drei verschiedene Handlungen enden; eine für die Kategorie A1, eine für B10 und eine für C100. Ich kann dies mit drei verschiedenen Codes tun, aber ich möchte in der Lage sein, eine Schleife oder einen anderen einzelnen Code zu verwenden, um alle drei Diagramme auf derselben Seite auszuführen. In Wirklichkeit habe ich ein großes Dataset (4.000 Zeilen) und möchte einige IDs auf einer Seite (etwa 5 auf einer Seite) darstellen. 

Ich hoffe das macht Sinn. Danke für Ihre Hilfe. 

Hier ist mein Versuch, sie einzeln zu zeichnen:

für A1:

data_A1 <- A[which(A$x_1 == "A1"), ]
plot(data_A1$z_2, data_A1$z_1)

Ich habe auch so etwas versucht, aber Fehlermeldungen bekommen

for ( i in A$x_1[[i]]){

plot(A[which(A$x_1==A$x_1[[i]]), ], aspect = 1)
}
13
John_dydx

Ein einfacher Ansatz mit Schleifen wäre

for (cat in unique(x_1)){
  d <- subset(A, x_1 == cat)
  plot(d$z_1, d$z_2)
}

unique(x_1) liefert Ihnen alle eindeutigen Werte von x_1. Dann erhalten Sie für jeden dieser Werte eine entsprechende Teilmenge und verwenden Sie diese Teilmenge zum Plotten.

14
Mark Heckmann

Um zu verstehen, warum Ihr ursprünglicher Code nicht funktioniert hat:

Das Einrichten der Daten funktioniert gut

x_1 <- c("A1", "A1", "A1", "B10", "B10", "B10","B10", "C100", "C100", "C100")
z_1 <- rnorm(10, 70) 
z_2 <- rnorm(10, 1.7)
A <- data.frame(x_1, z_1, z_2)

Die Einzelhandlung funktioniert gut, aber wie gesagt in einem Kommentar, die which ist nicht erforderlich

data_A1 <- A[which(A$x_1 == "A1"), ] # your way
plot(data_A1$z_2, data_A1$z_1)

data_A1 <- A[A$x_1 == "A1", ]    # deleting which() makes it cleaner
with(data_A1, plot(z_2, z_1))    # you can also use with() to save typing

Nun die for-Schleife. Sehen wir uns eine einfache for-Schleife in R an (ziemlich nahe am Beispiel in ?"for"):

for (i in 1:5) {
   print(1:i)
}

Ziemlich unkompliziert ist 1:5c(1, 2, 3, 4, 5), also zuerst i1, dann 2, usw. Ihre for-Schleife hat ein Problem in dieser ersten Zeile:

for (i in A$x_1[[i]]) { ## already a problem

i ist A$x_1[[i]]? Das funktioniert nicht, i ist noch nicht definiert. Außerdem ist A$x_1 ein Vektor und keine Liste. Daher sollten Sie [[ nicht verwenden, um ihn zu subsetieren. Aber wir wollen noch keine Untermenge, wir wollen einen Vektor der Werte, die i annehmen soll. Was wir in diesem Fall wollen, ist for (i in c("A1", "B10", "C100")), aber wir möchten es auch programmgesteuert machen, anstatt alle möglichen Möglichkeiten einzugeben. Es gibt einige Möglichkeiten, dies zu erreichen:

unique(A$x_1) # as in Mark's solution
levels(A$x_1) # works because A$x_1 is a factor

Wir können einen dieser Ausdrücke nach in setzen. Ich habe Ihren [[ beim Plotaufruf in [ geändert. [[ gilt nur für Listen. Ich habe auch die unnötige which() entfernt

for (i in unique(A$x_1)) {   # this line is good
    plot(A[A$x_1==A$x_1[i], ], aspect = 1)  # still a problem
}

Erinnern wir uns daran, welche Werte i annehmen: "A1", "B10", "C100". Was wird A$x_1 == A$x_1["A1"] geben? Nichts sinnvolles.

for (i in unique(A$x_1)) {  
    plot(A[A$x_1 == i, ], aspect = 1)  # getting there
}

Der obige Code stellt etwas dar und ist ordentlich, aber es ist nicht das, was Sie wollen. Es gibt eine Reihe von Warnungen, die uns alle sagen, dass aspect kein gültiges Argument ist, also löschen wir es. Wenn Sie sich die Grafik anschauen, werden Sie sehen, dass es 3 Variablen darstellt, weil wir nicht gesagt haben, was Sie auf die X- und Y-Achse setzen sollen.

for (i in unique(A$x_1)) {   
    plot(A[A$x_1==i, "z_2"], A[A$x_1==i, "z_1"])  # z_2 on x, z_1 on y 
}   # Works!!!

Beachten Sie, dass dies fast identisch mit Marks Antwort ist. Sie müssen i und j nicht für Schleifen verwenden, er hat cat verwendet. Es empfiehlt sich, einen aussagekräftigeren Namen zu verwenden ... Jetzt wollen wir uns etwas einfallen lassen:

for (i in unique(A$x_1)) {   
    plot(A[A$x_1==i, "z_2"], A[A$x_1==i, "z_1"],
         xlim = range(A$z_2), ylim = range(A$z_1), # base the axes on full data range
         main = paste("Plot of", i))  # Give each a title
}

Nächstes Mal: ​​Vergiss nicht, dass du winzige Teile des Codes ausführen kannst, um zu sehen, was sie sind. Wenn Sie eine Zeile wie for (i in A$x_1[[i]]) haben, bei der Sie nicht sicher sind, ob sie richtig ist, geben Sie an der Konsole A$x_1[[i]] ein. Dies hilft Ihnen hoffentlich dabei herauszufinden, dass Sie i nicht definiert haben

for (i in A$x_1)

dann führen Sie A$x_1 aus und stellen fest, dass die Länge 10 beträgt. Sie möchten 3 Diagramme, nicht 10, also benötigen Sie i, um 3 unterschiedliche Werte zu nehmen, usw.

13
Gregor

Vielleicht brauchen Sie keine Schleife. Versuchen Sie es mit ggplots facet_grid () . Hier ist die Dokumentation , voller Beispiele.

library(ggplot2)
library(reshape2)

melted_a <- melt(A)


ggplot(melted_a, aes(variable, value)) +
  geom_jitter() +
  facet_grid(. ~ x_1)

ggplot(melted_a, aes(variable, value)) +
  geom_jitter() +
  facet_grid(variable ~ x_1)

Edit Möglicherweise löst dies dieses Problem. Wenn Sie jedoch viele Diagramme mit ähnlicher Struktur erstellen möchten, können Sie eine Funktion erstellen und aes_string() anstelle von aes() verwenden. Hinweis: Ich bin kein Experte für das Schreiben von Funktionen, daher könnte wahrscheinlich jemand sie bearbeiten und verbessern. (nicht getestet)

ggplot_fun <- function(data, x, y, rowfacet, colfacet, ...){
  p <- ggplot(data, aes_string(x, y))
  p <- p + geom_jitter()
  p <- p + facet_grid(as.formula(sprintf("%s ~ %s", rowfacet, colfacet))
}

ggplot_fun(melted_a, variable, value, variable, x_1)

Idee aus dieser Frage .

3
marbel

Sie verändern auch die Daten, zum Beispiel wie hier ....

Wenn ich Daten-Plots und Xlab, Ylab und Titel des Plots mit bestimmten Details haben möchte ...

 for ( i in 1:length(unique(wheeldata$Date)) ){
     d <- subset( wheeldata, Date == unique ( wheeldata$Date )[i] )
     plot(d$X, d$Y, xlab = "X", ylab = "Y", main = paste0("Date: ",  unique(d$Date)) )
 }
1
Manoj Kumar