2016-04-15 6 views
1

タスクが効率的に、このデータからイベントを抽出することである。R:イベントの効率的な抽出(変数が連続的に増加)

data <- structure(
      list(i = c(1, 1, 1, 2, 2, 2), t = c(1, 2, 3, 1, 3, 4), x = c(1, 1, 2, 1, 2, 3)), 
      .Names = c("i", "t", "x"), row.names = c(NA, -6L), class = "data.frame" 
     ) 

> data 
    i t x 
1 1 1 1 
2 1 2 1 
3 1 3 2 
4 2 1 1 
5 2 3 2 
6 2 4 3 

tは時間であり、そしてxは選択の数である、のはi事実を呼ぶことにしましょうitである。

イベントは、1つのファクトの選択の途切れないシーケンスです。ファクト1は、t = 1からt = 3の間ですべて選択され、合計4つの選択肢があります。しかし、事実2は、t = 1からt = 1(合計= 1)、t = 3からt = 4(合計= 5)の2つのイベントに分割されます。そのため、イベント・データ・フレームは、このように見えることになっている:

> event 
    i from to sum 
1 1 1 3 4 
2 2 1 1 1 
3 2 3 4 5 

このコードが必要とされているものを行います。

event <- structure(
      list(i = logical(0), from = logical(0), to = logical(0), sum = logical(0)), 
      .Names = c("i", "from", "to", "sum"), row.names = integer(0), 
      class = "data.frame" 
     ) 
l <- nrow(data) # get rows of data frame 
c <- 1 # set counter 
d <- 1 # set initial row of data to start with 
e <- 1 # set initial row of event to fill 
repeat{ 
    event[e,1] <- data[d,1] # store "i" in event data frame 
    event[e,2] <- data[d,2] # store "from" in event data frame 
    while((data[d+1,1] == data[d,1]) & (data[d+1,2] == data[d,2]+1)){ 
     c <- c+1 
     d <- d+1 
     if(d >= l) break 
    } 
    event[e,3] <- data[d,2] # store "to" in event data frame 
    event[e,4] <- sum(data[(d-c+1):d,3]) # store "sum" in event data frame 
    c <- 1 
    d <- d+1 
    e <- e+1 
} 

問題は、このコードは、データからイベントを抽出するために3日かかるということです私のデータフレームは500万行を持っています。

これをより効率的にするにはどうすればよいですか?

P .:私のコードには、終了に関連する小さなバグもあります。

P.P.S:データは最初にiでソートされ、次にtでソートされます。データフレームを仮定し

答えて

1

このdplyrの実装が高速であれば試すことができますか?

library(dplyr) 

data <- structure(
    list(fact = c(1, 1, 1, 2, 2, 2), timing = c(1, 2, 3, 1, 3, 4), x = c(1, 1, 2, 1, 2, 3)), 
    .Names = c("fact", "timing", "x"), row.names = c(NA, -6L), class = "data.frame" 
) 

group_by(data, fact) %>% 
    mutate(fromto=cumsum(c(0, diff(timing) > 1))) %>% 
    group_by(fact, fromto) %>% 
    summarize(from=min(timing), to=max(timing), sumx=sum(x)) %>% 
    select(-fromto) %>% 
    ungroup() 

このデータはどのように実装されますか?あなたの助けのための

library(data.table) 
data <- structure(
    list(fact = c(1, 1, 1, 2, 2, 2), timing = c(1, 2, 3, 1, 3, 4), x = c(1, 1, 2, 1, 2, 3)), 
    .Names = c("fact", "timing", "x"), row.names = c(NA, -6L), class = "data.frame" 
) 
setDT(data)[, fromto:=cumsum(c(0, diff(timing) > 1)), by=fact] 
event <- data[, .(from=min(timing), to=max(timing), sumx=sum(x)), by=c("fact", "fromto")][,fromto:=NULL] 

##results when i enter event in the R console and my data.table package version is data.table_1.9.6 
> event 
    fact from to sumx 
1: 1 1 3 4 
2: 2 1 1 1 
3: 2 3 4 5 
> str(event) 
Classes ‘data.table’ and 'data.frame': 3 obs. of 4 variables: 
$ fact: num 1 2 2 
$ from: num 1 1 3 
$ to : num 3 1 4 
$ sumx: num 4 1 5 
- attr(*, ".internal.selfref")=<externalptr> 
> dput(event) 
structure(list(fact = c(1, 2, 2), from = c(1, 1, 3), to = c(3, 
1, 4), sumx = c(4, 1, 5)), row.names = c(NA, -3L), class = c("data.table", 
"data.frame"), .Names = c("fact", "from", "to", "sumx"), .internal.selfref = <pointer: 0x0000000000120788>) 

リファレンス detect intervals of the consequent integer sequences

+0

あなたの最初の実装は、私の500万行のために15日ではなく150秒かかりました:)本当にありがとうございます。 2回目の実装では、私は働くことができませんでした。私は最初の行を実行し、次に "イベント< - データ[..."。コードは大丈夫ですか?私はdata.tableパッケージが好きです。 – hyco

+0

ありがとうございます。コードをそのまま実行してください。それ以上のイベントデータを導入しないでください。 – chinsoon12

+0

あなたのdata.table実装を確認してください。私がそれを実行すると、最後の行には何の効果もないようです。しかし、以前は、あなたのfromtoコラムは私には意味がありません。 – hyco

1

data$tに従ってソートされて、あなたはこの

event <- NULL 
for (i in unique(data$i)) { 
    x <- data[data$i == i, ] 
    ev <- cumsum(c(1, diff(x$t)) > 1) 
    smry <- lapply(split(x, ev), function(z) c(i, range(z$t), sum(z$x))) 
    event <- c(event, smry) 
} 
event <- do.call(rbind, event) 
rownames(event) <- NULL 
colnames(event) <- c('i', 'from', 'to', 'sum') 

結果が行列ではなく、データフレームであるような何かを試すことができます。

+0

Thxを。残念ながら、あなたのアルゴリズムは私より10倍遅いです。 – hyco

+0

あまりにも悪い...アルゴリズムのどこにボトルネックがあるのか​​を理解するために、 'Rprof'のようなプロファイリングツールを使いたいかもしれません。 –