3

この時点で発生したタイムスタンプと特定のイベント タイプを含む CSV ファイルがあります。私が欲しいのは、特定のイベントタイプの発生回数を 6 分間隔でカウントすることです。

入力データは次のようになります。

date,type
"Sep 22, 2011 12:54:53.081240000","2"
"Sep 22, 2011 12:54:53.083493000","2"
"Sep 22, 2011 12:54:53.084025000","2"
"Sep 22, 2011 12:54:53.086493000","2"

次のコードを使用して、データを読み込んで修復します。

> raw_data <- read.csv('input.csv')
> cured_dates <- c(strptime(raw_data$date, '%b %d, %Y %H:%M:%S', tz="CEST"))
> cured_data <- data.frame(cured_dates, c(raw_data$type))
> colnames(cured_data) <- c('date', 'type')

修復後、データは次のようになります。

> head(cured_data)
                 date type
1 2011-09-22 14:54:53    2
2 2011-09-22 14:54:53    2
3 2011-09-22 14:54:53    2
4 2011-09-22 14:54:53    2
5 2011-09-22 14:54:53    1
6 2011-09-22 14:54:53    1

xts と Zoo のサンプルをたくさん読んだのですが、なんとなく腑に落ちません。出力データは次のようになります。

date                       type   count
2011-09-22 14:54:00 CEST   1      11
2011-09-22 14:54:00 CEST   2      19
2011-09-22 15:00:00 CEST   1      9
2011-09-22 15:00:00 CEST   2      12
2011-09-22 15:06:00 CEST   1      23
2011-09-22 15:06:00 CEST   2      18

Zoo の集計関数は有望に見えます。次のコード スニペットを見つけました。

# aggregate POSIXct seconds data every 10 minutes
tt <- seq(10, 2000, 10)
x <- zoo(tt, structure(tt, class = c("POSIXt", "POSIXct")))
aggregate(x, time(x) - as.numeric(time(x)) %% 600, mean)

今、これを自分のユースケースにどのように適用できるか疑問に思っています。

私が試したように素朴です:

> zoo_data <- zoo(cured_data$type, structure(cured_data$time, class = c("POSIXt", "POSIXct")))
> aggr_data = aggregate(zoo_data$type, time(zoo_data$time), - as.numeric(time(zoo_data$time)) %% 360, count)
Error in `$.zoo`(zoo_data, type) : not possible for univariate zoo series

私は R にあまり自信がないことを認めなければなりませんが、試してみます。:-)

私はちょっと迷っています。誰かが私を正しい方向に向けることができますか?

どうもありがとう!乾杯、アレックス。

これは、私のデータの小さなサブセットに対する dput の出力です。データ自体は約 8000 万行です。

structure(list(date = structure(c(1316697885, 1316697885, 1316697885, 
1316697885, 1316697885, 1316697885, 1316697885, 1316697885, 1316697885, 
1316697885, 1316697885, 1316697885, 1316697885, 1316697885, 1316697885, 
1316697885, 1316697885, 1316697885, 1316697885, 1316697885, 1316697885, 
1316697885, 1316697885), class = c("POSIXct", "POSIXt"), tzone = ""), 
    type = c(2L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 
    1L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 2L)), .Names = c("date", 
"type"), row.names = c(NA, -23L), class = "data.frame")
4

2 に答える 2

3

を使用して読み取ることができread.csv、最初の列を6分間隔にビニングされた日時に変換し、1のダミー列を追加します。次にread.zoo、タイプを分割し、ダミー列を集計して、読み直します。

# test data

Lines <- 'date,type
"Sep 22, 2011 12:54:53.081240000","2"
"Sep 22, 2011 12:54:53.083493000","2"
"Sep 22, 2011 12:54:53.084025000","2"
"Sep 22, 2011 12:54:53.086493000","2"
"Sep 22, 2011 12:54:53.081240000","3"
"Sep 22, 2011 12:54:53.083493000","3"
"Sep 22, 2011 12:54:53.084025000","3"
"Sep 22, 2011 12:54:53.086493000","4"'

library(zoo)
library(chron)

# convert to chron and bin into 6 minute bins using trunc
# Also add a dummy column of 1's 
# and remove any leading space (removing space not needed if there is none)

DF <- read.csv(textConnection(Lines), as.is = TRUE)
fmt <- '%b %d, %Y %H:%M:%S'
DF <- transform(DF, dummy = 1,
         date = trunc(as.chron(sub("^ *", "", date), format = fmt), "00:06:00"))

# split and aggregate

z <- read.zoo(DF, split = 2, aggregate = length)

上記のテストデータを使用すると、ソリューションは次のようになります。

> z
                    2 3 4
(09/22/11 12:54:00) 4 3 1

長い形式は時系列を構成しないのに対し、上記の形式は時系列を構成するため、上記は広い形式で行われていることに注意してください。タイプごとに1つの列があります。テストデータにはタイプ2、3、4があるため、3つの列があります。

(この方法は6分のグループへのビニングに適しているため、ここではchronを使用しtruncました。chronはタイムゾーンをサポートしていません。これは、考えられる多くのタイムゾーンエラーの1つを作成できないため、利点となる可能性がありますが、POSIXctが必要な場合は変換します。この式は、time(z) <- as.POSIXct(paste(as.Date.dates(time(z)), times(time(z)) %% 1))R News 4/1の記事のいずれかの表に示されていますが、それ以降に発生したと思われるバグを回避するためas.Date.datesだけに使用したものではありません。使用することもできますが、異なるタイムゾーンになります。)as.Datetime(z) <- as.POSIXct(time(z))

編集:

元のソリューションは日付にビニングされましたが、その後、6分間にビニングしたいので、ソリューションが改訂されたことに気付きました。

編集:

コメントに基づいて改訂。

于 2011-09-23T14:27:29.300 に答える
2

あなたはほとんどそこまで来ています。あとは、そのデータの動物園っぽいバージョンを作成し、aggregate.zoo コードにマップするだけです。時間とタイプの両方で分類したいので、aggregate.zoo への 2 番目の引数はもう少し複雑にする必要があり、手段ではなくカウントが必要なので、length() を使用する必要があります。countこれは基本的な R または Zoo 関数ではないと思いcountます。ワークスペースに表示される唯一の関数は pkg:plyr からのものであるため、aggregate.zoo でどれだけうまく機能するかわかりません。lengthほとんどの人がベクトルに期待するように機能しますが、data.frames を操作するときに驚くことがよくあります。で必要なものが得られない場合はlength、次のことを確認する必要がありますNROW代わりに動作します (データ レイアウトでは両方とも成功します): 新しいデータ オブジェクトでは、最初に型引数を配置する必要があります。そして、集計/動物園は単一のカテゴリ分類子のみを処理することが判明したため、as.vector を入れて動物園性を削除する必要があります。

with(cured_data, 
     aggregate(as.vector(x), list(type = type, 
                                   interval=as.factor(time(x) - as.numeric(time(x)) %% 360)),
                             FUN=NROW) 
 )

#  interval            x 
#1 2011-09-22 09:24:00 12
#2 2011-09-22 09:24:00 11

これは、コードを取得した場所から変更された例です (WizaRd Dirk による SO の例): 任意の時間枠で値の発生を集計 (カウント)

tt <- seq(10, 2000, 10)
x <- zoo(tt, structure(tt, class = c("POSIXt", "POSIXct")))
aggregate(as.vector(x), by=list(cat=as.factor(x), 
     tms = as.factor(index(x) - as.numeric(index(x)) %% 600)), length)

   cat                 tms  x
1    1 1969-12-31 19:00:00 26
2    2 1969-12-31 19:00:00 22
3    3 1969-12-31 19:00:00 11
4    1 1969-12-31 19:10:00 17
5    2 1969-12-31 19:10:00 28
6    3 1969-12-31 19:10:00 15
7    1 1969-12-31 19:20:00 17
8    2 1969-12-31 19:20:00 16
9    3 1969-12-31 19:20:00 27
10   1 1969-12-31 19:30:00  8
11   2 1969-12-31 19:30:00  4
12   3 1969-12-31 19:30:00  9
于 2011-09-23T13:26:06.643 に答える