29437


パネルデータ分析のために同じIDの標本のデータを`tydir`のパッケージを用いて幾つかの行に分解したいと考えています。  
元のデータにはイベント発生時の時間(L1~L3)が入っています。

[code]

    id L1 L2 L3 now
    1  30 35 NA  42
    2  22 26 31  33
    3  31 31 NA  34
    7  33 NA NA  35
    44 NA NA NA  28
    
[/code]

(他の共変量もたくさん含まれていますが今回の変形に必要なところだけ抜き出しました。）

改造後のデータは

[code]

    id event start end count
    1      1     0  30     1
    1      1    30  35     2
    1      0    35  42     3
    2
    2
    2
    3
    3
    3
    7      1     0  33     1
    7      0    33  35     2
    44     0     0  28     1
    
[/code]

という感じです。`count=1`の`start`は0、`end`はL1,`count=2`の`start`はL1、`end`はL2です。

`tidyr`で`gather`すれば良さげですが、あまり使い慣れておらず詳しい使い方がわからないので詳しい方に教えていただきたいです。よろしくお願い致します。

data

[code]

    structure(list(id = c(1, 2, 3, 7, 44), L1 = c(30, 22, 
    31, 33, NA), L2 = c(35, 26, 31, NA, NA), L3 = c(NA, 31, 
    NA, NA, NA), now = c(42, 33, 34, 35, 28)), .Names = c("id", 
    "L1", "L2", "L3", "now"), class = "data.frame", row.names = c(NA, 
    -5L))
    
[/code]

**追記**  
ここに書いてある方法だと`melt`で全ての列が分解されてしまいました。  
`tidyr`の`gather`を`melt`と入れ替え、また分解する列を指定したらうまくいきました。  
`tidyr::gather("カラム名を収納する列","値を収納する列",分解する列の指定)`  
という感じで  
`tidyr::gather("name","end",L1:now)`と指定しました。


CC BY-SA 3.0
2016-10-08T11:20:42.870
29432
2016-10-10T07:27:09.987
2016-10-10T07:27:09.987
12457
12457
question
r
tidyrを用いたパネルデータの整備


最初の`gather()`以外は全て`dplyr`となっております、`tidyr`なテクニック (?) をご希望でしたら申し訳ございません。

基本的手順

[code]

    # long化・ソート、id毎にend列をずらし (0挿入) start列作成、行数=count、end=nowはevent=0、含NA行削除
    id variable end　　   id variable end start     id variable end start count event
     1       L1  30　　    1       L1  30     0      1       L1  30     0     1     1
     1       L2  35　　    1       L2  35    30      1       L2  35    30     2     1
     1      now  42　　    1      now  42    35      1      now  42    35     3     0
     1       L3  NA　　    1       L3  NA    42
    
[/code]

[code]

    library(dplyr); library(tidyr)   # [EDITED] reshape2ではなくtidyrを使用
    
    data2 <- data %>% 
      gather(variable, end, -id) %>%                       # long形式に展開、値はend列として使用
      arrange(id, end) %>% group_by(id) %>%                # id & end値を基準にソート、idでグループ化
      do(mutate(., start = lag(.$end, n=1, default=0),     # group毎にendをひとつずらしてstartを作成
                   count = 1:nrow(.))) %>%                 # またgroup内で何行目かをcountに使用
      na.omit() %>% ungroup() %>%                          # naを含む行の削除、グループ解除
      mutate(event = ifelse(.$variable=="now", 0, 1)) %>%  # nowを使用しているか否かでevent値を算出
      select(-variable)                                    # 不要列削除
    
    data2 <- data2[,c(1, 5, 3, 2, 4)]                      # 列並び替え
    
[/code]

[code]

    > data2
    # A tibble: 13 × 5
          id event start   end count
       <int> <dbl> <dbl> <int> <int>
    1      1     1     0    30     1
    2      1     1    30    35     2
    3      1     0    35    42     3
    4      2     1     0    22     1
    5      2     1    22    26     2
    6      2     1    26    31     3
    7      2     0    31    33     4
    8      3     1     0    31     1
    9      3     1    31    31     2
    10     3     0    31    34     3
    11     7     1     0    33     1
    12     7     0    33    35     2
    13    44     0     0    28     1
    
[/code]

余談

[code]

    class(1)    # [1] "numeric"
    class(1L)   # [1] "integer"
    
[/code]


CC BY-SA 3.0
2016-10-08T16:04:50.417
29437
2016-10-09T15:08:28.840
2016-10-09T15:08:28.840
15653
15653
29432
answer


`data.table`というパッケージを用いるなら読みやすくなるとおもいます：

[code]

    library(data.table)
    setDT(DT)
    
    out.DT = 
      melt(DT, id.vars = "id",
           value.name = "end", na.rm = TRUE
           )[ , c("event", "count", "start") := 
                .(+(variable != "now"), seq_len(.N),
                  shift(end, fill = 0)), keyby = id
              ][ , variable := NULL]
    out.DT[]
    #     id end event count start
    #  1:  1  30     1     1     0
    #  2:  1  35     1     2    30
    #  3:  1  42     0     3    35
    #  4:  2  22     1     1     0
    #  5:  2  26     1     2    22
    #  6:  2  31     1     3    26
    #  7:  2  33     0     4    31
    #  8:  3  31     1     1     0
    #  9:  3  31     1     2    31
    # 10:  3  34     0     3    31
    # 11:  7  33     1     1     0
    # 12:  7  35     0     2    33
    # 13: 44  28     0     1     0
    
[/code]


CC BY-SA 3.0
2016-10-09T17:37:29.703
29447
2016-10-09T19:52:33.337
2016-10-09T19:52:33.337
18598
18598
29432
answer