So zeichnen Sie alle Spalten eines Datenrahmens in R.

76

Der Datenrahmen hat n Spalten und ich möchte n Diagramme erhalten, ein Diagramm für jede Spalte.

Ich bin ein Neuling und spreche nicht fließend R, trotzdem habe ich zwei Lösungen gefunden.

Der erste funktioniert, aber er druckt den Spaltennamen nicht (und ich brauche sie!):

data <- read.csv("sample.csv",header=T,sep=",")
for ( c in data ) plot( c, type="l" )

Der zweite funktioniert besser, weil er den Spaltennamen druckt:

data <- read.csv("sample.csv",header=T,sep=",")
for ( i in seq(1,length( data ),1) ) plot(data[,i],ylab=names(data[i]),type="l")

Gibt es bessere (aus Sicht der R-Sprache) Lösungen?

Alessandro Jacopson
quelle
2
In Ihrem zweiten zweiten Beispiel würde ich die Schleife so initialisieren for(i in seq_along(dat))und meine Daten auch nicht aufrufen data.
Gavin Simpson
3
Sie read.csvkönnen auf reduziert werden, read.csv("sample.csv")da die anderen Argumente nur auf ihre Standardwerte gesetzt werden.
G. Grothendieck

Antworten:

85

Das ggplot2Paket erfordert ein wenig Lernen, aber die Ergebnisse sehen wirklich gut aus, Sie erhalten schöne Legenden und viele andere nette Funktionen, ohne viel Code schreiben zu müssen.

require(ggplot2)
require(reshape2)
df <- data.frame(time = 1:10,
                 a = cumsum(rnorm(10)),
                 b = cumsum(rnorm(10)),
                 c = cumsum(rnorm(10)))
df <- melt(df ,  id.vars = 'time', variable.name = 'series')

# plot on same grid, each series colored differently -- 
# good if the series have same scale
ggplot(df, aes(time,value)) + geom_line(aes(colour = series))

# or plot on different plots
ggplot(df, aes(time,value)) + geom_line() + facet_grid(series ~ .)

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

Prasad Chalasani
quelle
Schöne Antwort, aber warum brauchen Sie eigentlich eine Umformung?
Eliasah
Danke @VerenaHaunschmid Ich habe das später herausgefunden :-)
eliasah
43

Es gibt eine sehr einfache Möglichkeit, alle Spalten aus einem Datenrahmen mithilfe separater Bedienfelder oder desselben Bedienfelds zu zeichnen:

plot.ts(data)

Welche Ausbeuten (wobei X1 - X4 Spaltennamen sind):

Geben Sie hier die Bildbeschreibung ein

Schauen Sie sich? Plot.ts für alle Optionen an.

Wenn Sie nicht mehr Kontrolle über Ihre Plotfunktion haben und keine Schleife verwenden möchten, können Sie auch Folgendes tun:

par(mfcol = c(ncol(data), 1))
Map(function(x,y) plot(x, main =y), data, names(data))
Matti Pastell
quelle
Vielen Dank, auch wenn es sich um Zeitreihen handelt, kann es mir helfen, meine Daten zu erfassen. Ich mag Einzeiler!
Alessandro Jacopson
7
Nur eine kleine Anmerkung: Wenn Sie 'plot.type = c ("single")' hinzufügen, wird Ihre Serie auf einem einzelnen Plot anstatt auf separaten Feldern gezeichnet: data <- data.frame(x=c(rnorm(10)),y=c(rnorm(10)),z=c(rnorm(10))) plot.ts(data,plot.type=c("single"),lty=1:3)
Geek On Acid
@GeekOnAcid +1, vielen Dank für den Hinweis auf "Single".
Alessandro Jacopson
Wenn Sie verwenden möchten single, sollten Sie auch Folgendes hinzufügen: col=rainbow(ncol(my.data))oder etwas Ähnliches, um die Zeilen lesbar zu halten.
Heller Stern
13

Sie können durch Reifen springen und wandeln Sie Ihre Lösung auf einen lapply, sapplyoder applyAnruf. (Ich sehe, dass @jonw einen Weg zeigt, dies zu tun.) Abgesehen davon ist das, was Sie bereits haben, vollkommen akzeptabler Code.

Wenn dies alles Zeitreihen oder ähnliche sind, ist das Folgende möglicherweise eine geeignete Alternative, bei der jede Reihe in einem eigenen Bereich in einem einzelnen Darstellungsbereich dargestellt wird. Wir verwenden das zooPaket, da es bestellte Daten wie diese sehr gut verarbeitet.

require(zoo)
set.seed(1)
## example data
dat <- data.frame(X = cumsum(rnorm(100)), Y = cumsum(rnorm(100)),
                  Z = cumsum(rnorm(100)))
## convert to multivariate zoo object
datz <- zoo(dat)
## plot it
plot(datz)

Welches gibt: Beispiel für Zoo-Plotfunktionen

Gavin Simpson
quelle
11

Ich bin überrascht, dass niemand erwähnt hat matplot. Dies ist sehr praktisch, wenn Sie nicht jede Linie in separaten Achsen zeichnen müssen. Nur ein Befehl:

matplot(y = data, type = 'l', lty = 1)

Verwenden Sie ?matplotdiese Option, um alle Optionen anzuzeigen.

Um die Legende hinzuzufügen, können Sie die Farbpalette festlegen und dann hinzufügen:

mypalette = rainbow(ncol(data))
matplot(y = data, type = 'l', lty = 1, col = mypalette)
legend(legend = colnames(data), x = "topright", y = "topright", lty = 1, lwd = 2, col = mypalette)
Rustam Guliev
quelle
Was ist matlab.dark.palette, woher kommt es?
Alessandro Jacopson
1
@AlessandroJacopson Es ist eine Farbpalettenfunktion, die ich normalerweise benutze. Es ist aus dem hyperSpecPaket. Aber es wäre besser, hier eine bekanntere Funktion zu verwenden, also habe ich sie geändert rainbow. Wenn Sie sich der Palettenfunktionen nicht bewusst sind, schauen Sie sich diese an ?rainbow. Entschuldigung für die Verwirrung.
Rustam Guliev
7

Mit einigen der obigen Tipps (insbesondere danke @daroczig für das names(df)[i]Formular) druckt diese Funktion ein Histogramm für numerische Variablen und ein Balkendiagramm für Faktorvariablen. Ein guter Anfang, um einen Datenrahmen zu erkunden:

par(mfrow=c(3,3),mar=c(2,1,1,1)) #my example has 9 columns

dfplot <- function(data.frame)
{
  df <- data.frame
  ln <- length(names(data.frame))
  for(i in 1:ln){
    mname <- substitute(df[,i])
      if(is.factor(df[,i])){
        plot(df[,i],main=names(df)[i])}
        else{hist(df[,i],main=names(df)[i])}
  }
}

Beste Wünsche, Mat.

MatW
quelle
4

Mit lattice:

library(lattice)

df <- data.frame(time = 1:10,
                 a = cumsum(rnorm(10)),
                 b = cumsum(rnorm(10)),
                 c = cumsum(rnorm(10)))

form <- as.formula(paste(paste(names(df)[- 1],  collapse = ' + '),  
                         'time',  sep = '~'))

xyplot(form,  data = df,  type = 'b',  outer = TRUE)
Oscar Perpiñán
quelle
3

Mit der Option können Sie den Titel (und auch den Titel der Achsen über xlabund ylab) angeben main. Z.B:

plot(data[,i], main=names(data)[i])

Und wenn Sie zeichnen möchten (und speichern) jede Variable eines Datenrahmen, die Sie verwenden sollten png, pdfoder jede andere Grafiktreiber Sie benötigen, und nach dieser Ausgabe einen dev.off()Befehl. Z.B:

data <- read.csv("sample.csv",header=T,sep=",")
for (i in 1:length(data)) {
    pdf(paste('fileprefix_', names(data)[i], '.pdf', sep='')
    plot(data[,i], ylab=names(data[i]), type="l")
    dev.off()
}

Oder zeichnen Sie alle Diagramme mit dem mfrowParameter von auf dasselbe Bild par(). Beispiel: Verwenden Sie diese Option par(mfrow=c(2,2), um die nächsten 4 Diagramme in dasselbe "Bild" aufzunehmen.

daroczig
quelle
3

Ich habe kein R auf diesem Computer, aber hier ist ein Riss. Sie können parmehrere Diagramme in einem Fenster anzeigen oder auf diese Weise einen Klick veranlassen, bevor die nächste Seite angezeigt wird.

plotfun <- function(col) 
  plot(data[ , col], ylab = names(data[col]), type = "l")
par(ask = TRUE)
sapply(seq(1, length(data), 1), plotfun)
J. Win.
quelle
2

Leider bietet ggplot2 keine Möglichkeit, dies (einfach) zu tun, ohne Ihre Daten in ein Langformat umzuwandeln. Sie können versuchen, dagegen anzukämpfen, aber die Datentransformation ist einfacher. Hier alle Methoden, einschließlich meltvon reshape2, gathervon tidyr und pivot_longervon tidyr: Umformen von data.frame vom Breit- zum Langformat

Hier ist ein einfaches Beispiel mit pivot_longer:

> df <- data.frame(time = 1:5, a = 1:5, b = 3:7)
> df
  time a b
1    1 1 3
2    2 2 4
3    3 3 5
4    4 4 6
5    5 5 7

> df_wide <- df %>% pivot_longer(c(a, b), names_to = "colname", values_to = "val")
> df_wide
# A tibble: 10 x 3
    time colname   val
   <int> <chr>   <int>
 1     1 a           1
 2     1 b           3
 3     2 a           2
 4     2 b           4
 5     3 a           3
 6     3 b           5
 7     4 a           4
 8     4 b           6
 9     5 a           5
10     5 b           7

Wie Sie sehen können, werden pivot_longerdie ausgewählten Spaltennamen in die von names_to(Standard "Name") angegebenen Werte und die langen Werte in die von values_to(Standard "Wert") angegebenen Werte eingefügt . Wenn ich mit den Standardnamen einverstanden bin, kann ich use verwenden df %>% pivot_longer(c("a", "b")).

Jetzt können Sie wie gewohnt zeichnen, z.

ggplot(df_wide, aes(x = time, y = val, color = colname)) + geom_line()

Geben Sie hier die Bildbeschreibung ein

qwr
quelle
Ich würde require(tidyr)und require(ggplot2)zu Ihrer Antwort hinzufügen , damit es ein minimales Arbeitsbeispiel wird.
Alessandro Jacopson
@AlessandroJacopson Ich dachte, ich hätte deutlich gemacht, dass diese erforderlich sind. Wie auch immer, ist die MWE nützlich, wenn der Code mit Erklärungen durchsetzt ist?
qwr
Für mich ist es nützlich, trotzdem ist es Geschmackssache, danke für Ihre Antwort.
Alessandro Jacopson
1

Falls die Spaltennamen in der .csvDateidatei nicht gültig sind R-Name:

data <- read.csv("sample.csv",sep=";",head=TRUE)
data2 <- read.csv("sample.csv",sep=";",head=FALSE,nrows=1)

for ( i in seq(1,length( data ),1) ) plot(data[,i],ylab=data2[1,i],type="l")
Alessandro Jacopson
quelle
1
Da Sie nur die erste Zeile von Daten2 verwenden, wäre es effizienter sein, gesetzt nrows = 1in read.csv.
Rustam Guliev