質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.57%

R言語:DataFrame中の連続したデータでグループ化したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,036

nomoty

score 11

R言語のDataFrameの処理についての質問になります。
以下に示しますDF1をDF2に変換したいです。
変換するためのよい方法、コードをご教示いただけないでしょうか?
※なお、実際の処理対象のDataFrameは約30万レコードになります。

【DF1】

ID place date tool
001 A 2018/10/01 XXX
001 A 2018/10/02 XXX
001 A 2018/10/03 XXX
001 A 2018/10/04 YYY
001 A 2018/10/05 YYY
001 A 2018/10/06 XXX
001 A 2018/10/07 XXX

【DF2】

ID place start_date end_date tool
001 A 2018/10/01 2018/10/03 XXX
001 A 2018/10/04 2018/10/05 YYY
001 A 2018/10/06 2018/10/07 XXX

【処理内容】
ID,place,toolが同一の連続したレコードのまとまりを1つのグループとみなし、
グループ中で最も古いdateをstart_date、最も新しいdateをend_dateとします。
ex) 10/01~03のグループの場合、start_dateは10/01、end_dateは10/03となります。
なお、10/01~03のグループと10/06~07のグループはID,place,toolが同一ですが
日付が連続していないので、別々のグループとみなします。

【補足】

# DF1→DF2への変換
library(dplyr)
DF2 <-
  DF1 %>% 
  group_by(ID, place, tool) %>% 
  mutate(start_date = min(date)) %>% 
  mutate(end_date = max(date)) %>% 
  distinct(ID, place, start_date, end_date, tool)

上記のようなコードを書いた場合、以下のようにID,place,toolが同一のレコードで
まとまってしまうため、そうならないための方法を探しています。

ID place start_date end_date tool
001 A 2018/10/01 2018/10/07 XXX
001 A 2018/10/04 2018/10/05 YYY
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

check解決した方法

0

library(dplyr)

DF1$date <- DF1$date %>% as.Date()
DF1$number <- c(1:nrow(DF1))

DF1_semi <- DF1 %>%
  mutate(ID_lead = lead(ID, default = "UA"),
         place_lead = lead(place, default = "UA"),
         tool_lead  = lead(tool, default = "UA"),
         ID_lag     = lag(ID, default = "UA"),
         place_lag  = lag(place, default = "UA"),
         tool_lag   = lag(tool, default = "UA")
  ) %>%
  mutate(flg_end   = ifelse((ID == ID_lead & place == place_lead & tool == tool_lead), 0, 1),
         flg_start = ifelse((ID == ID_lag  & place == place_lag  & tool == tool_lag) , 0, 1),
         tmp       = ifelse((flg_start == 0 & flg_end == 0), 0, 1)
  ) %>%
  filter(tmp == 1) %>%
  arrange(number) %>% 
  select(number, ID, place, date, tool, flg_start, flg_end)

DF2 <- DF1_semi %>%
  group_by(ID, place, tool) %>%
  mutate(date_lead = as.Date(ifelse(is.na(lead(date)), date, lead(date)), origin="1970-01-01")) %>%
  ungroup() %>%
  filter(flg_start == 1) %>%
  rename(start_date = date, end_date = date_lead) %>%
  arrange(number) %>% 
  select(ID, place, start_date, end_date, tool) %>%
  as.data.frame()

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/08 15:03

    有識者に情報提供いただき、解決しました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.57%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る