Wie werden die Minutenwerte einer Woche zu Stundenwerten zusammengefasst?


15

Wie würden Sie stündliche Mittelwerte für mehrere Datenspalten für einen täglichen Zeitraum erhalten und die Ergebnisse für zwölf "Hosts" in derselben Grafik anzeigen? Das heißt, ich möchte für Daten im Wert von mehreren Wochen grafisch darstellen, wie ein 24-Stunden-Zeitraum aussieht. Das letztendliche Ziel wäre es, zwei Sätze dieser Daten vor und nach der Probenahme zu vergleichen.

            dates         Host CPUIOWait CPUUser CPUSys
1 2011-02-11 23:55:12     db       0      14      8
2 2011-02-11 23:55:10     app1     0       6      1
3 2011-02-11 23:55:09     app2     0       4      1

Ich konnte xyplot (CPUUser ~ dates | Host) mit gutem Effekt ausführen. Anstatt jedoch jedes Datum in der Woche anzuzeigen, möchte ich, dass die X-Achse die Stunden des Tages darstellt.

Der Versuch, diese Daten in ein xts-Objekt zu übertragen, führt zu Fehlern wie "order.by erfordert ein geeignetes zeitbasiertes Objekt".

Hier ist ein str () des Datenrahmens:

'data.frame':   19720 obs. of  5 variables:
$ dates    : POSIXct, format: "2011-02-11 23:55:12" "2011-02-11 23:55:10" ...
$ Host     : Factor w/ 14 levels "app1","app2",..: 9 7 5 4 3 10 6 8 2 1 ...  
$ CPUIOWait: int  0 0 0 0 0 0 0 0 0 0 ...
$ CPUUser  : int  14 6 4 4 3 10 4 3 4 4 ...
$ CPUSys   : int  8 1 1 1 1 3 1 1 1 1 ...

UPDATE: Nur zum späteren Nachschlagen habe ich mich für einen Boxplot entschieden, um sowohl den Median als auch die "Ausreißer" anzuzeigen.

Im Wesentlichen:

Data$hour <- as.POSIXlt(dates)$hour  # extract hour of the day
boxplot(Data$CPUUser ~ Data$hour)    # for a subset with one host or for all hosts
xyplot(Data$CPUUser ~ Data$hour | Data$Host, panel=panel.bwplot, horizontal=FALSE)

Vielen Dank


Ich vermute, Sie erhalten diese Fehler, xts()weil die datesSpalte ein Faktor ist.
Joshua Ulrich

Ich bin wirklich neu in R ... Ich habe die Datumsspalte aus der Strptime-Funktion erstellt. Die Originaldaten stammen aus read.csv.
Scott Hoffman

1
Sehen wir uns str()den data.frame an.
Roman Luštrik

@ Roman Danke für die Funktion str (), das war mir nicht bewusst. Wenn ich die Factor-Spalte loswird, kann ich ein xts-Objekt wie dieses erzeugen, x <-xts (d [, 3: 5], order.by = d [, 1]). Ich konnte mich dann bei .hourly bewerben, was die Daten von 19720 Objekten auf 480 verkürzt. Ich bin mir nicht sicher, ob dies mich dahin bringt, wo ich will, aber ich denke, jetzt bin ich näher dran.
Scott Hoffman

Antworten:


14

Hier ist ein Ansatz, der cut () verwendet, um die entsprechenden stündlichen Faktoren und ddply () aus der Plyr-Bibliothek zur Berechnung der Mittelwerte zu erstellen.

library(lattice)
library(plyr)

## Create a record and some random data for every 5 seconds 
## over two days for two hosts.
dates <- seq(as.POSIXct("2011-01-01 00:00:00", tz = "GMT"),
             as.POSIXct("2011-01-02 23:59:55", tz = "GMT"),
             by = 5)
hosts <- c(rep("host1", length(dates)), rep("host2", 
           length(dates)))
x1    <- sample(0:20, 2*length(dates), replace = TRUE)
x2    <- rpois(2*length(dates), 2)
Data  <- data.frame(dates = dates, hosts = hosts, x1 = x1, 
                    x2 = x2)

## Calculate the mean for every hour using cut() to define 
## the factors and ddply() to calculate the means. 
## getmeans() is applied for each unique combination of the
## hosts and hour factors.
getmeans  <- function(Df) c(x1 = mean(Df$x1), 
                            x2 = mean(Df$x2))
Data$hour <- cut(Data$dates, breaks = "hour")
Means <- ddply(Data, .(hosts, hour), getmeans)
Means$hour <- as.POSIXct(Means$hour, tz = "GMT")

## A plot for each host.
xyplot(x1 ~ hour | hosts, data = Means, type = "o",
       scales = list(x = list(relation = "free", rot = 90)))

Vielen Dank dafür ... Ich glaube, ich muss die Frage neu formulieren oder eine neue stellen. Wenn ich mir diese Frage anschaue , stats.stackexchange.com/questions/980/… , denke ich jetzt, dass es nicht genau das ist, wonach ich strebe .
Scott Hoffman

@JVM Können Sie erklären, wie die Funktion getmeans funktioniert und warum Sie nicht nur die Funktionen mean oder colMeans verwendet haben?
Scott Hoffman

1
Die Funktion ddply () schneidet den ursprünglichen Datensatz in Teilmengen, die durch Hosts und Stunden definiert sind. Diese werden dann als data.frame an getmeans () übergeben. Für Ihre Aufgabe würde die Verwendung von colMeans () wahrscheinlich gut funktionieren, aber Sie müssten wahrscheinlich zuerst die Spalten entfernen, die Sie nicht benötigen. Das Schöne an der Verwendung von ddply () auf diese Weise ist, dass Sie jeden beliebigen Wert berechnen können, für den Sie sich interessieren könnten. zB sd (), range () usw.
Jason Morgan

6

Die Aggregation funktioniert auch ohne Verwendung von zoo(mit Zufallsdaten aus 2 Variablen für 3 Tage und 4 Hosts wie bei JWM). Ich gehe davon aus, dass Sie für jede Stunde Daten von allen Hosts haben.

nHosts <- 4  # number of hosts
dates  <- seq(as.POSIXct("2011-01-01 00:00:00"),
              as.POSIXct("2011-01-03 23:59:30"), by=30)
hosts  <- factor(sample(1:nHosts, length(dates), replace=TRUE),
                 labels=paste("host", 1:nHosts, sep=""))
x1     <- sample(0:20, length(dates), replace=TRUE)  # data from 1st variable
x2     <- rpois(length(dates), 2)                    # data from 2nd variable
Data   <- data.frame(dates=dates, hosts=hosts, x1=x1, x2=x2)

Ich bin mir nicht ganz sicher, ob Sie den Durchschnitt nur innerhalb einer Stunde oder innerhalb einer Stunde über alle Tage berechnen möchten. Ich mache beides.

Data$hFac <- droplevels(cut(Data$dates, breaks="hour"))
Data$hour <- as.POSIXlt(dates)$hour  # extract hour of the day

# average both variables over days within each hour and host
# formula notation was introduced in R 2.12.0 I think
res1 <- aggregate(cbind(x1, x2) ~ hour + hosts, data=Data, FUN=mean)
# only average both variables within each hour and host
res2 <- aggregate(cbind(x1, x2) ~ hFac + hosts, data=Data, FUN=mean)

Das Ergebnis sieht so aus:

> head(res1)
  hour hosts        x1       x2
1    0 host1  9.578431 2.049020
2    1 host1 10.200000 2.200000
3    2 host1 10.423077 2.153846
4    3 host1 10.241758 1.879121
5    4 host1  8.574713 2.011494
6    5 host1  9.670588 2.070588

> head(res2)
                 hFac hosts        x1       x2
1 2011-01-01 00:00:00 host1  9.192308 2.307692
2 2011-01-01 01:00:00 host1 10.677419 2.064516
3 2011-01-01 02:00:00 host1 11.041667 1.875000
4 2011-01-01 03:00:00 host1 10.448276 1.965517
5 2011-01-01 04:00:00 host1  8.555556 2.074074
6 2011-01-01 05:00:00 host1  8.809524 2.095238

Ich bin mir auch nicht ganz sicher, welche Art von Grafik Sie verwenden möchten. Hier ist die Bare-Bones-Version eines Diagramms für nur die erste Variable mit separaten Datenzeilen für jeden Host.

# using the data that is averaged over days as well
res1L <- split(subset(res1, select="x1"), res1$hosts)
mat1  <- do.call(cbind, res1L)
colnames(mat1) <- levels(hosts)
rownames(mat1) <- 0:23
matplot(mat1, main="x1 per hour, avg. over days", xaxt="n", type="o", pch=16, lty=1)
axis(side=1, at=seq(0, 23, by=2))
legend(x="topleft", legend=colnames(mat1), col=1:nHosts, lty=1)

Dieselbe Grafik für die Daten, die nur innerhalb einer Stunde gemittelt werden.

res2L <- split(subset(res2, select="x1"), res2$hosts)
mat2  <- do.call(cbind, res2L)
colnames(mat2) <- levels(hosts)
rownames(mat2) <- levels(Data$hFac)
matplot(mat2, main="x1 per hour", type="o", pch=16, lty=1)
legend(x="topleft", legend=colnames(mat2), col=1:nHosts, lty=1)

Gute Antwort, es gibt eine Menge, die ich nicht kenne, also muss ich es ausprobieren. Wenn ich jedoch meine Daten mit Ihren Methoden betrachte, denke ich, dass ich auch die Höhepunkte in meinen Daten anzeigen muss. Vielen Dank
Scott Hoffman

2

Sie können die aggregate.zooFunktion aus dem Paket auscheckenzoo : http://cran.r-project.org/web/packages/zoo/zoo.pdf

Charlie


Können Sie mir helfen, zu verstehen, warum ich bei der Ausführung NAs erhalte?
Scott Hoffman

Hallo Scott, ich habe die aggregate.zooFunktion nicht wirklich benutzt , obwohl ich das zooPaket benutzt habe. Haben Sie zuerst sichergestellt, dass es sich bei Ihrem Objekt um ein zooObjekt handelt? Die Dokumentation, auf die ich verwiesen habe, sollte Ihnen dabei helfen.
Charlie
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.