2013-07-26 128 views
5

我有一個由其他列表和數據框組成的複雜列表。我需要將這個列表簡化爲只包含數據幀 - 因此每個第二級列表應該製作成單獨的第一級數據幀。將列表的複雜列表轉換爲數據框列表

下面是可再現的例子:

dd<-data.frame(x=1:3,y=4:6) 
l1<-list(dd,list(dd,dd)) 
#original list 
l1 
[[1]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

[[2]] 
[[2]][[1]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

[[2]][[2]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

結果我需要得到

l2<-list(dd,dd,dd) 
l2 
[[1]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

[[2]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

[[3]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

我與功能unlist()和參數recursive=FALSE但在這種情況下,第一級數據幀試圖被轉換成兩個向量。我能想到的

unlist(l1,recursive=FALSE) 
$x 
[1] 1 2 3 

$y 
[1] 4 5 6 

[[3]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

[[4]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

回答

3

一種方法是檢查類的輸入(在運行lapply)是data.framelist,如果它是一個data.frame將其轉換爲的data.frame列表。這將導致整個列表成爲data.frames列表的列表。然後你可以使用unlistrecursive=FALSE如下:

unlist(lapply(l1, function(x) 
     if (class(x) == "data.frame") list(x) else x), recursive=FALSE) 
[[1]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

[[2]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

[[3]] 
    x y 
1 1 4 
2 2 5 
3 3 6 

這個工作的時候當然數據是你提到確切。它們是data.frames列表或data.frames列表列表。哦,歡迎來到SO(第一個問題)! :)

+0

謝謝!我一直在想相反的方向 - 如何分割列表。將數據幀轉換爲數據幀列表的想法很好。 –

+0

我會盡量避免'class(x)==「data.frame」'並使用'is.data.frame'來代替。 – shadow

+0

不知道這裏有什麼問題避免使用它。你能詳細說明一下嗎? 'is.data.frame'在內部使用'inherits',它會爲從'data.frame'派生的對象給出TRUE。例如在'data.table'上也是如此。如果這是可取的,那麼是的,使用'inherits'更好。 – Arun