1

さまざまな時間に発生する特定の数のさまざまなイベントを持つアイテムのデータフレームがあります。たとえば、サッカーのさまざまな試合でイベント (ゴール、コーナー、レッドカードなど) があったとします。各チームの特定の時間前に発生した各イベントの数を、各ゲーム (ゲームごとに時間が異なる場合) でカウントしたいと考えています。

したがって、イベントのデータフレーム (C はコーナー、G はゴール、R はレッドカード) を次のように作成できます。

events <- data.frame(
            game_id = c(1,   1,   1,   1,   1,   1,   2,   2,   2,   2,   2,   2,   2),
            team    = c(1,   1,   2,   1,   2,   2,   1,   1,   2,   2,   2,   1,   1),
            event_id= c('C', 'C', 'C', 'G', 'C', 'R', 'C', 'C', 'C', 'C', 'G', 'G', 'C'),
            time    = c(5,   14,   27,  67,  78,  87, 10,  19,  33,  45,  60,  78,  89))

次のように、各イベントを検索する時間の別のデータフレーム:

eventTime <- data.frame(
             game_id = c(1, 2),
             time    = c(45, 65))

したがって、ゲーム 1 では、45 分前に各チームの各イベントの数を数えたいと考えています。ゲーム 2 では、同じことを行いたいのですが、60 分では次のように返します。

game_id time t1_C t1_G t1_R t2_C t2_G t2_R
    1    45   2    0     0   1    0     0
    2    65   2    0     0   2    1     0

ゲーム 1 では、チーム 1 は 45 分前に 2 つのコーナー、0 ゴール、0 枚のレッドカードを持っていたのに対し、チーム 2 は 1 つのコーナー、0 ゴール、0 枚のレッドカードを持っていました。

apply を使用してデータを調べてサブセット化し、行をカウントアップすることでこれを行ってきましたが、数千の行があり、これには多くの時間がかかります。

これを行う最も簡単な方法を知っている人はいますか?

編集: game_id が eventTime データフレームに異なる時間で複数回表示される可能性があることに言及しませんでした。たとえば、game_id が時間 45 と 70 で 2 回出現する可能性がある場合、それぞれの固有のイベント/時間の組み合わせに対して適切なカウントを取得したいと考えています。

4

3 に答える 3

2

これを段階的に実行して理解すると、意図した結果が得られるはずです。また、必要に応じてコードを削減する余地があります-

library(data.table)
library(reshape)
library(reshape2)

events <- data.table(events)
eventTime <- data.table(eventTime)
eventTime[,TimeLimit := time]

setkeyv(eventTime,c('game_id','time'))
setkeyv(events,c('game_id','time'))

eventsSubset <- eventTime[events, roll = -Inf][!is.na(TimeLimit)]

eventsSubset <- eventsSubset[,list(Freq = .N), by = c('team','event_id','game_id','TimeLimit')]

eventsReshaped <- cast(eventsSubset, game_id + TimeLimit ~ event_id+team, fun.aggregate = sum, value = "Freq")

出力

> eventsReshaped 
  game_id TimeLimit C_1 C_2 G_2
1       1        45   2   1   0
2       2        65   2   2   1

PS- これは、データセット全体で、各タイプのイベントが少なくとも 1 回発生することを前提としています。この特定のコードの出力は、見つかったイベントのみを集計しているため、結果にすべてのイベントとチームの組み合わせが含まれているわけではありません。これが起こらないようにしたい場合は、元のデータセットにダミーのエントリを追加できます。

于 2013-10-10T13:49:41.390 に答える
1

イベント時間の名前を「時間」とは異なるものに変更すると役立ちます。

names(eventTime)[2] <- "stopTime"

停止時間をメイン データ セットにマージします。

events <- merge(events,eventTime)

便利なパッケージをロード:

library(reshape2)
library(plyr)

停止時刻の前にイベントを保持するためのサブセット:

e2 <- subset(events,time<stopTime)

ゲーム * チーム * イベントのテーブルを作成し、それを長い形式に「溶かす」:

m2 <- melt(with(e2,table(game_id,team,event_id)))

好みのワイド フォームに並べ替えます。

m3 <- dcast(m2,game_id~team+event_id)

停止時間を結果に戻します。

merge(eventTime,m3)
于 2013-10-10T14:00:28.667 に答える
1

お二人のおかげで、どちらの回答も私の最初の質問には答えたと思いますが、編集された質問にはうまくいきません。ただし、両方の回答の一部を組み合わせて、自分に合ったものを取得しました。

Ben Bolkers の回答の最初の部分を使用して、データ フレームをマージし、時間が stopTime 未満の場所をサブセット化しました。次に、データテーブルに変換し、Coderemifa の回答の最後の 2 行を使用しました。したがって、次のように

library(reshape)
library(reshape2)
library(plyr)
names(eventTime)[2] <- "stopTime"
events <- merge(events,eventTime)
e2 <- subset(events,time<stopTime)
eventsSubset <- data.table(e2)
eventsSubset <- eventsSubset[,list(Freq = .N), by=c('team','event_id','game_id','stopTime')]
eventsReshaped <- cast(eventsSubset, game_id + stopTime~ event_id+team, fun.aggregate = sum, value = "Freq")
于 2013-10-10T15:31:53.940 に答える