2016-12-18 6 views
2

リストをdata.frameに変換するとき、Rはすべてのサブリストの名前を連結することによって自動的に変数に名前を付けます。しかし、リストの長さが1のときは最後の名前しか保持していないようです。変数名にフルパス名を付ける方法はありますか?リストからすべての名前をdata.frameに保持する

MWE:

> l <- list(a = list(b = 1), c = 2) 
> l 
$a 
$a$b 
[1] 1 
$c 
[1] 2 

> data.frame(l) 
    b c 
1 1 2 

> ll <- list(a = list(b = 1, bb = 1), c = 2) 
> data.frame(ll) 
    a.b a.bb c 
1 1 1 2 

ここで私はそれがdata.frame(ll)の場合と同様にdata.frame(l)の変数の名前としてa.bを持っていると思います。

+0

しかし、問題は 'unlist'は' as.data.frame'と同じ動作をしません。 'list(a = 1、b = 1:3)' – clemlaflemme

+0

私は可能な限り、最短の変数のリサイクルを使用します。もちろん、長さは_compatible_ – clemlaflemme

答えて

2

可能な解決策は、as.data.frame()有するデータフレームにリストを変換する関数を作成し、次いで第二の工程で所望の値に名前を設定しますlist_names()が難しい定義、明らか

list_df <- function(list) { 
    df <- as.data.frame(list) 
    names(df) <- list_names(list) 
    return (df) 
} 

部。一つの可能​​性は、ネストされたリストを再帰することです:

list_names <- function(list) { 

    recursor <- function(list, names) { 
    if (is.list(list)) { 
     new_names <- paste(names, names(list), sep = ".") 
     out <- unlist(mapply(list, new_names, FUN = recursor)) 
    } else { 
     out <- names 
    } 
    return(out) 
    } 

    new_names <- unlist(mapply(list, names(list), FUN = recursor)) 
    return(new_names) 
} 

これはあなたの二つの例のために働く:

l <- list(a = list(b = 1), c = 2) 
ll <- list(a = list(b = 1, bb = 1), c = 2) 
list_df(l) 
## a.b c 
## 1 1 2 
list_df(ll) 
## a.b a.bb c 
## 1 1 1 2 

また、ネストされていないリストのためだけでなく、より深いとリストのために働きます入れ子:

ls <- list(a = 1, b = 3) 
lc <- list(a = list(b = 1, bb = 1), c = 2, d = list(e = list(f = 1, ff = 2), ee = list(fff = 5))) 
list_df(ls) 
## a b 
## 1 1 3 
list_df(lc) 
## a.b a.bb c d.e.f d.e.ff d.ee.fff 
## 1 1 1 2  1  2  5 
+1

でなければなりません。興味深い再帰関数です。私はそれらをうまくやったことはなかった –

関連する問題