1週間分のデータを時間単位で集計するにはどうすればよいですか?


15

複数のデータ列、1日ごとに1時間ごとの平均を取得し、同じグラフに12個の「ホスト」の結果を表示するにはどうすればよいですか?つまり、1週間分のデータについて、24時間の期間をグラフ化したいと思います。最終的な目標は、サンプリングの前後にこのデータの2つのセットを比較することです。

            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

私はxyplot(CPUUser〜dates | Host)を効果的に実行できました。ただし、週の各日付を表示するのではなく、X軸を1日の時間にしたいと思います。

このデータをxtsオブジェクトに取得しようとすると、「order.byには適切な時間ベースのオブジェクトが必要」などのエラーが発生します

データフレームのstr()は次のとおりです。

'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 ...

更新:将来の参考のために、中央値と「外れ値」の両方を示すために、箱ひげ図を使用することにしました。

基本的に:

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)

ありがとう


列が要因であるxts()ため、これらのエラーが発生すると推測していますdates
ジョシュアウルリッヒ

私は本当にRが初めてです... strptime関数から日付列を作成しました。元のデータはread.csvからのものです。
スコットホフマン

1
str()data.frameを見てみましょう。
ローマンルシュトリック

@Roman str()関数をありがとう、私はそれを知りませんでした。したがって、Factor列を取り除くと、x <-xts(d [、3:5]、order.by = d [、1])のようなxtsオブジェクトを生成できます。その後、.hourlyに適用できました。これにより、データは19720オブジェクトから480まで短縮されます。
スコットホフマン

回答:


14

次に、cut()を使用して適切な毎時係数を作成し、plyrライブラリーからddply()を使用して平均を計算する1つの方法を示します。

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

これに感謝します...しかし、私は質問を言い換えるか、新しい質問をする必要があるかもしれないと思います。この質問stats.stackexchange.com/questions/980/…を見ると、手段を取得することは、私が望んでいることとまったく同じではないと思います。
スコットホフマン

@JVM getmeans関数がどのように機能するのか、なぜ平均またはcolMeans関数を使用しなかったのかを説明できますか?
スコットホフマン

1
ddply()関数は、元のデータセットをホストと時間で定義されたサブセットにカットします。次に、これらをdata.frameとしてgetmeans()に渡します。あなたのタスクでは、colMeans()を使用することはおそらくうまくいくでしょうが、おそらく最初に不要な列を削除する必要があるでしょう。この方法でddply()を使用する利点は、興味のある任意の統計を計算できることです。例:sd()、range()など
ジェイソンモーガン

6

集計も使用せずに機能しますzoo(3日間の2つの変数からのランダムデータと、JWMのような4つのホストを使用)。1時間ごとにすべてのホストからのデータがあると仮定します。

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)

1時間以内に平均化するのか、それとも1日以内に1時間以内に平均化するのか、完全にはわかりません。両方やります。

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)

結果は次のようになります。

> 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

また、あなたが望むグラフのタイプについても完全にはわかりません。これは、各ホストに個別のデータ行を持つ最初の変数のみのグラフの基本バージョンです。

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

各時間内でのみ平均化されるデータの同じグラフ。

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)

いい返事、そこに私はよく知らないたくさんので、それを試してみる必要があります。それでも、あなたの方法で私のデータを見て、私も私のデータの高いポイントを示す必要があると考えています。ありがとう
スコットホフマン

2

aggregate.zooパッケージから関数をチェックアウトする場合がありますzoohttp : //cran.r-project.org/web/packages/zoo/zoo.pdf

チャーリー


これを実行するときにNAが表示される理由を理解してもらえますか?
スコットホフマン

こんにちはスコット、私はパッケージaggregate.zooを使用しましたが、実際には関数を使用していませんzoo。オブジェクトがzoo最初にオブジェクトであることを確認しましたか?私が指摘したドキュメントは、そこに役立つはずです。
チャーリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.