2016-05-10 2 views
1

リストのリストをdata.frameに変換したい。最初は各サブリストの長さが1であったので、stack(as.data.frame(...))を使用しましたが、スタックは複数列を生成できるように継ぎ目がありませんdata.frame。だから何それを達成することの最善の方法:スタックを使用して複数の列のデータフレームを生成する方法は?

# works fine with only sublists of length 1 
l = list(a = sample(1:5, 5), b = sample(1:5, 5)) 
> stack(as.data.frame(l)) 
    values ind 
1  5 a 
2  4 a 
3  1 a 
4  2 a 
5  3 a 
6  2 b 
7  1 b 
8  3 b 
9  5 b 
10  4 b 

今私のリストは、リストのリストである:

l = list(a = list(first = sample(1:5, 5), sec = sample(1:5, 5)), b = list(first = sample(1:5, 5), sec = sample(1:5, 5))) 
stack(as.data.frame(l)) 
    values  ind 
1  4 a.first 
2  5 a.first 
3  3 a.first 
4  1 a.first 
5  2 a.first 
6  3 a.sec 
7  5 a.sec 
8  1 a.sec 
9  2 a.sec 
10  4 a.sec 
11  5 b.first 
12  4 b.first 
13  3 b.first 
14  1 b.first 
15  2 b.first 
16  3 b.sec 
17  4 b.sec 
18  1 b.sec 
19  2 b.sec 
20  5 b.sec 

私はabと2で、まだ列indを持っているしたいと思いながら、列firstsec

+0

予想される出力は何ですか? – Sotos

答えて

2

我々は(c)ネストされた要素(L1「」)を連結することでlistを平らにすることができ、から部分文字列を取得します'l1'( 'nm1'と 'nm2')の、 'l1'で 'nm1'(すなわち、接頭辞を削除して得られる部分文字列) 'nm2'(接尾辞は.で始まる部分文字列を取り除いて得られる部分文字列)をとstack( 'lst')にループして 'l1'のを設定します。次に、 'ind'列(listのすべての要素で同じなので、最初のリスト要素 - lst[[1]][2]から取得します)を 'value'列、つまり最初の列でcbindとします。

l1 <- do.call(c, l) 
nm1 <- sub("[^.]+\\.", "", names(l1)) 
nm2 <- sub("\\..*", "", names(l1)) 
lst <- lapply(split(setNames(l1, nm2), nm1), stack) 
cbind(lst[[1]][2],lapply(lst, `[[`, 1)) 
# ind first sec 
#1 a  1 1 
#2 a  5 5 
#3 a  4 4 
#4 a  3 3 
#5 a  2 2 
#6 b  3 4 
#7 b  4 5 
#8 b  2 2 
#9 b  1 3 
#10 b  5 1 

それとも我々が期待される出力を得ることができますdplyr/purrrを使用。ここで

library(purrr) 
library(dplyr) 
l1 <- transpose(l) 
n1 <- names(l1) 
l1 %>% 
    map(stack) %>% 
    bind_cols %>% 
    setNames(., make.unique(names(.))) %>% 
    select(ind, matches("value")) %>% 
    setNames(., c("ind", n1)) 
#  ind first sec 
# (fctr) (int) (int) 
#1  a  1  1 
#2  a  5  5 
#3  a  4  4 
#4  a  3  3 
#5  a  2  2 
#6  b  3  4 
#7  b  4  5 
#8  b  2  2 
#9  b  1  3 
#10  b  5  1 
+0

okコメントは削除されていますが、実際には各サブリストに2つ以上のエントリ(ここでは 'first'と' sec')があっても動作します。ありがとう – clemlaflemme

+0

@clemlaflemmeアップデートをありがとう。私はもっ​​と柔軟にするもう一つの方法を追加しました – akrun

1

は別のアプローチです:

df <- stack(as.data.frame(l)) 
# split names of variables 
indVars <- strsplit(as.character(df$ind), split="\\.") 
# add variables to data.frame 
df$letters <- sapply(indVars, function(i) i[1]) 
df$order <- sapply(indVars, function(i) i[2]) 

# get final data.frame 
cbind("order"=unstack(df, letters~order)[,1], unstack(df, values~order)) 
関連する問題