2017-12-21 16 views
0

複数の列でgroup_by()を使用する際に問題があります。例えば、データセットは以下の通りです:2つの変数をグループ化して要約する方法

dput(test) 
structure(list(timestamp = structure(c(1506676980, 1506676980, 
1506676980, 1506677040, 1506677280, 1506677340, 1506677460), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), plusminus = c(-1, 1, 1, 1, 1, 1, -1 
), AP = structure(c(1L, 2L, 2L, 2L, 2L, 1L, 2L), .Label = c("A", 
"B"), class = "factor")), .Names = c("timestamp", "plusminus", 
"AP"), row.names = c(NA, -7L), class = "data.frame") 

次のように見えます:

  timestamp plusminus AP 
1 2017-09-29 09:23:00  -1 A 
2 2017-09-29 09:23:00   1 B 
3 2017-09-29 09:23:00   1 B 
4 2017-09-29 09:24:00   1 B 
5 2017-09-29 09:28:00   1 B 
6 2017-09-29 09:29:00   1 A 
7 2017-09-29 09:31:00  -1 B 

私は次の操作を行いたいと思います:

  1. '内の各レベルの累計を計算しますAP '変数
  2. は、実行中の合計の最大値を1分ごとに集計します。

    # A tibble: 7 x 4 
    # Groups: AP [2] 
          timestamp plusminus  AP total 
           <dttm>  <dbl> <fctr> <dbl> 
    1 2017-09-29 09:23:00  -1  A -1 
    2 2017-09-29 09:23:00   1  B  1 
    3 2017-09-29 09:23:00   1  B  2 
    4 2017-09-29 09:24:00   1  B  3 
    5 2017-09-29 09:28:00   1  B  4 
    6 2017-09-29 09:29:00   1  A  0 
    7 2017-09-29 09:31:00  -1  B  3 
    

    が、私は」:

    test %>% group_by(AP) %>% mutate(total = cumsum(plusminus)) 
    

    与える:

      timestamp total AP 
    1 2017-09-29 09:23:00 -1 A 
    2 2017-09-29 09:23:00  2 B 
    3 2017-09-29 09:24:00  3 B 
    4 2017-09-29 09:28:00  4 B 
    5 2017-09-29 09:29:00  0 A 
    6 2017-09-29 09:31:00  3 B 
    

    それは経由パート1を実行するために簡単です。つまり

、私はこの出力をしたいですパート2のやり方が分かりません。つまり、私はどのようにして集計を実行するのかを知りたいのです。後者のデータフレームの第2の行は所望の出力を与えるように抑制される。

答えて

1

実行中の合計を計算した後、タイムスタンプとAPの各ペアを取得するためにグループ分けし直してから、最大値を維持するように要約する必要があります。最後の値(最大値ではなく)を保持したい場合は、最後の行を保持することもできます(slice(n())で行うこともできます)。ここでは、答えは同じですが、あなたのデータに当てはまることを確認してください。

test %>% 
    group_by(AP) %>% 
    mutate(total = cumsum(plusminus)) %>% 
    group_by(timestamp, AP) %>% 
    summarise(maxTotal = max(total) 
      , lastTotal = total[n()]) 

はここ

  timestamp  AP maxTotal lastTotal 
       <dttm> <fctr> <dbl>  <dbl> 
1 2017-09-29 09:23:00  A  -1  -1 
2 2017-09-29 09:23:00  B  2   2 
3 2017-09-29 09:24:00  B  3   3 
4 2017-09-29 09:28:00  B  4   4 
5 2017-09-29 09:29:00  A  0   0 
6 2017-09-29 09:31:00  B  3   3 
+0

ありがとうございました。Lyngbakrはもう少し早かったので、私は彼にチェックマークを付けます。 – Stijn

+1

Lyngbakrの答えは最大値ではなく* last *値を与えることに注意してください。 –

+0

申し訳ありませんが、あなたは正しいです – Stijn

0

を与えるdata.tableアプローチです:

DATA

p <- structure(list(timestamp = structure(c(1506676980, 1506676980, 
1506676980, 1506677040, 1506677280, 1506677340, 1506677460), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), plusminus = c(-1, 1, 1, 1, 1, 1, -1 
), AP = structure(c(1L, 2L, 2L, 2L, 2L, 1L, 2L), .Label = c("A", 
"B"), class = "factor")), .Names = c("timestamp", "plusminus", 
"AP"), row.names = c(NA, -7L), class = "data.frame") 

CODE

library(data.table) 
p <- as.data.table(p) 
p[, total:= cumsum(plusminus), by = AP][, max(total), by = .(AP, lubridate::round_date(timestamp, unit = "min"))] 

OUTPUT

AP   lubridate V1 
1: A 2017-09-29 09:23:00 -1 
2: B 2017-09-29 09:23:00 2 
3: B 2017-09-29 09:24:00 3 
4: B 2017-09-29 09:28:00 4 
5: A 2017-09-29 09:29:00 0 
6: B 2017-09-29 09:31:00 3 

上記のスニペットは、所望の出力を得るために(あなたが%>%アプローチと、それは似て考えることができます) "連鎖" を使用しています。まず、累積合計をAPで取得し、それをtotalに保存します。 2番目のステップでは、APtimestamp(最も近い分)をグループ化し、新しく定義された変数totalの最大値を取得します。

私が見つけたのはdata.tableです。大規模なデータセットでは非常にうまく機能します。

関連する問題