2017-04-15 17 views
0

1つの列がリストであるデータフレームにデータがあります。R - リストのData_frameリストを整理して整理します

rand_lets <- function(){ 
    sample(letters[1:26], runif(sample(1:10, 1), min=5, max=12)) 
} 

example_data <- data.frame(ID = seq(1:5), 
          location = LETTERS[1:5], 
          observations = I(list(rand_lets(), 
               rand_lets(), 
               rand_lets(), 
               rand_lets(), 
               rand_lets()))) 

私は、リスト内の各要素が新しい列に分割されるように、リスト列を非公開にするには、エレガントなtidyverseアプローチを探しています:これは一例です。例えば、最初の行は次のようになります。もちろん

ID location observations observations.1 observations.3 observations.3 observations.4 observations.5 observations.6 observations.7 observations.8 observations.9 
1  A "y"   "b"    "m"    "u"    "x"    "j"    "t"    "i"    "v"    "w" 

をリストエントリがので、空のセルがNAであるべきである異なる長さであってもよいです。

どうすればいいですか?

+0

ロングフォームは、不自然なデータの方が便利ですが、実際に直接ワイドにしたい場合は、リスト列内のデータを構造化できます: 'example_data%>%mutate(observations = map(observations、〜as_data_frame (t(.x))))%>%unnest() ' – alistaire

+0

素晴らしいです。これは 'map()'の使い方です。私は長いフォームがより有用であることに同意するが、私はチュートリアルで自分のデータセットを使用し、ワイドフォームからロングフォームに移行するのが良い最初のレッスンです。 –

答えて

2

あなたが「長い」形式でデータを保存したい場合は、行うことができます:

example_data %>% unnest(observations) 
ID location observations 
1 1  A   e 
2 1  A   x 
3 1  A   w 
... 
44 5  E   u 
45 5  E   o 
46 5  E   z 

をあなたの例のように、「ワイド」の形式にデータを分散するために、あなたが行うことができます:

library(stringr) 

example_data %>% unnest(observations) %>% 
    group_by(location) %>% 
    mutate(counter=paste0("Obs_", str_pad(1:n(),2,"left","0"))) %>% 
    spread(counter, observations) 
 ID location Obs_01 Obs_02 Obs_03 Obs_04 Obs_05 Obs_06 Obs_07 Obs_08 Obs_09 Obs_10 Obs_11 
* <int> <fctr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> 
1  1  A  e  x  w  c  s  j  k  t  z <NA> <NA> 
2  2  B  k  u  d  h  z  x <NA> <NA> <NA> <NA> <NA> 
3  3  C  v  z  m  o  s  f  n  c  r  u  b 
4  4  D  z  i  m  s  a  v  n  r  e  t  x 
5  5  E  f  b  g  h  a  d  u  o  z <NA> <NA> 
+0

Awesome @ eipi10 - なぜ 'group_by(ID、location)'が必要でないのか説明できますか?IDによるグループは何らかの形で暗示されているようです。ところで、 'counter =' sprintf( "Obs_%02i"、1:n()) 'は見出しの書式を整えるためのより良い方法かもしれません。 – epi99

+1

ロケーションごとに複数のIDがある場合、またはその逆の場合は、 'group_by(ID、location)'を使用します。 – eipi10

関連する問題