2017-03-07 4 views
0

私は、ケースとその接点に関する幅広いデータセットを持っています。 (これは構成された例であり、実際のデータセットははるかに大きい)。複数の列を選択し、幅広い長方形に整形する

structure(list(record_id = structure(1:4, .Label = c("01-001", 
"01-002", "01-003", "01-004"), class = "factor"), place = structure(c(1L, 
2L, 1L, 1L), .Label = c("a", "b"), class = "factor"), sex = structure(c(2L, 
2L, 1L, 2L), .Label = c("F", "M"), class = "factor"), age = c(4L, 
13L, 28L, 44L), d02_1 = c(2L, 2L, NA, 2L), d02_2 = structure(c(3L, 
2L, 1L, 3L), .Label = c("", "F", "M"), class = "factor"), d02_3 = c(27L, 
16L, NA, 66L), d03_1 = c(3L, 3L, NA, 3L), d03_2 = structure(c(3L, 
3L, 1L, 2L), .Label = c("", "F", "M"), class = "factor"), d03_3 = c(14L, 
55L, NA, 12L), d04_1 = c(4L, NA, NA, NA), d04_2 = structure(c(2L, 
1L, 1L, 1L), .Label = c("", "M"), class = "factor"), d04_3 = c(7L, 
NA, NA, NA)), .Names = c("record_id", "place", "sex", "age", 
"d02_1", "d02_2", "d02_3", "d03_1", "d03_2", "d03_3", "d04_1", 
"d04_2", "d04_3"), row.names = c(NA, -4L), class = "data.frame") 

  • RECORD_IDは
  • 場所はケースが
  • 年齢は
  • セックスがケースの性別である場合の年齢で住んでいる場所である場合の一意な識別子である

  • d02_1、d03_1、d04_1 ... d0j_1は連絡先のIDですS

  • d02_2、d03_2、d04_2 ... d0j_2は、連絡先のセックス
  • d02_3、d03_3あり、d04_3 ... d0j_3は本当のデータセットでは、連絡先の年齢

あり、ケースごとに潜在的に多くの接点があります、および連絡先の特性に関する多くの変数が含まれます。すべての症例が接触するわけではありません。

私はすなわち、ケース/連絡先ごとに1行で、整頓形式にデータセットを再構築したい:

  id case place sex age 
1 01-001 1  a M 4 
2 01-001-2 0  a M 27 
3 01-001-3 0  a M 14 
4 01-001-4 0  a M 7 
5 01-002 1  b M 13 
6 01-002-2 0  b F 16 
7 01-002-3 0  b M 55 
8 01-003 1  a F 28 
9 01-004 1  a M 44 
10 01-004-2 0  a M 66 
11 01-004-3 0  a F 12 

私は(私は、各連絡先に関連する列名のベクトルを作成する必要がありますことを考えています列名の文字マッチングを使用する可能性があります)、これらの列を順番に選択し、それらを互いに追加したり(ケース/連絡先IDを連結する)、実際にはたくさんのコード行をコピーすることなく苦労します。より効率的な方法でなければなりませんか?

+1

これは役に立ちませんか?http://stackoverflow.com/questions/40229114/tidyrgather-multiple-columns-of-varying-types?rq=1基本的に同じように見えます。 – MrFlick

+0

読み込み時には 'na.strings = '''を設定するべきでしょう。それはあまり意味がありません/そこに空白を入れるのが難しくなります。 – Frank

答えて

0

これはあなたが探しているものですか?

これはいくつかの理由で醜い解決策ですが、私はそれが完了したと思います。

DF <- DF %>% 
    rename_(.dots=setNames(names(.), gsub('_1','_ContactID',names(.)))) %>% 
    rename_(.dots=setNames(names(.), gsub('_2','_sex',names(.)))) %>% 
    rename_(.dots=setNames(names(.), gsub('_3','_age',names(.)))) %>% 
    rename(d00_sex=sex,d00_age=age) %>% 
    mutate(d00_ContactID=1) %>% 
    gather(Var,Val,-record_id,-place) %>% 
    mutate(Val =ifelse(Val=='',NA,Val)) %>% 
    separate(Var,c('ContactLevel','Var'),sep='_') %>% 
    spread(Var,Val) %>% 
    arrange(record_id,ContactLevel) %>% 
    filter(!is.na(age),!is.na(ContactID),!is.na(sex)) %>% 
    mutate(age = as.numeric(age)) 

わかりやすくするために変数の名前を変更することから始めます。 (rename_行)

次に、ケース情報がContactID = 1である一貫したパターンにケース情報変数を配置します。 (enameおよびmutate行)

Gatherは、データをワイドからロングに変えますが、非常に醜い列を1つ残して、すべてのデータを文字に変換します。

separateは、連絡先IDとデータ列に古い列名を分割します(警告がトリガーされる醜い部分です)。

spreadは、年齢、性別、IDを列に再度開きます。この行では、これらのデータはあなたが望むものですが、まだ少しでもクリーンアップすることができます。

arrangeは必須ではありませんが、すべてのレコードIDをまとめます。

filterも必要ではなく、契約情報のない行を削除するだけです。

最後に、ageを文字から数字に変換するためにmutateを使用します。あなたが望むのであれば、ここで性別を因子に変えることもできますし、おそらくIDにも連絡することができます。

+0

はい - これは仕事です。 setNamesとgsubの使い方 –

関連する問題