2016-03-10 188 views
-1

我是R的總noob,我試過(並重試)來搜索以下問題的答案,但是我一直沒能得到任何建議解決方案做我感興趣的R:合併數據幀列表

我有一個名爲元素的兩個列表,每個元素指向具有相同佈局的數據幀。

(EDIT)

df1 <- data.frame(A=c(1,2,3),B=c("A","B","C")) 
df2 <- data.frame(A=c(98,99),B=c("Y","Z")) 
lst1 <- c(X=df1,Y=df2) 
df3 <- data.frame(A=c(4,5),B=c("D","E")) 
lst2 <- c(X=df3) 

(EDIT 2 )

S o似乎將多個數據幀存儲在列表中是一個壞主意,因爲它會將數據幀轉換爲列表。所以我會出去尋找另一種存儲一組命名數據幀的方法。

通常,兩個元素中元素的名稱可能部分重疊,完全重疊或根本不重疊。

我正在尋找一種方式將兩個清單合併成一個列表:

<some-function-sequence>(lst1, lst2) 
-> 
c(X=rbind(df1,df3),Y=df2) 

的東西-resulting這樣的:

[編輯:語法更改爲正確反映所需的結果(列表的數據的幀)] $ X AB 11.一種 2 2 B 3的3C 4 4 d 5 5] E

$X.B 
    A B 
1 98 Y 
2 99 Z 

即:

我已經從一個數字,如討論試圖解決方案

- 但我一直沒有找到合適的解決方案。一個普遍的問題似乎是數據框最終被應用'mapply/sapply/merge/...'轉換爲列表 - 並且通常也以我不感興趣的方式切片和/或合併。 :)

任何幫助,將非常感謝!

[溶液] 溶液似乎是收集數據幀list(...)之後由Pierre提出的解決辦法似乎得到所需的結果時改變使用的c(...)

+0

花一些時間來創建一些示例數據幀。僞代碼並不足以描述你正在使用的內部結構。 'c(a = ,..'會將數據幀分成列表元素,我懷疑你是真實的數據反映了這一點 –

+0

如果你有數據存儲在列表中在'list(a = df1,b = df2)'中,你可以使用split和rbind'lapply(split(c(lst1,lst2),names(c(lst1,lst2))),function(lst)do。電話(rbind,lst))' –

+0

感謝您的回覆Pierre。我已經嘗試了上面的建議,但一直未能實現。我已經在示例中添加了一些示例數據以及運行結果 – RBA

回答

0

下面是使用splitc像方面結合了建議的解決方案。請在底部閱讀警告:

s <- split(c(lst1, lst2), names(c(lst1,lst2))) 
lapply(s, function(lst) do.call(function(...) unname(c(...)), lst)) 
# $X.A 
# [1] 1 2 3 4 5 
# 
# $X.B 
# [1] "A" "B" "C" "D" "E" 
# 
# $Y.A 
# [1] 98 99 
# 
# $Y.B 
# [1] "Y" "Z" 

該解決方案是基於沒有因素爲字符串。它不會拋出錯誤,但因素將被轉換爲數字。下面我展示了我如何轉換數據以消除因素。讓我知道如果你需要的因素:

df1 <- data.frame(A=c(1,2,3),B=c("A","B","C"), stringsAsFactors=FALSE) 
df2 <- data.frame(A=c(98,99),B=c("Y","Z"), stringsAsFactors=FALSE) 
lst1 <- c(X=df1,Y=df2) 
df3 <- data.frame(A=c(4,5),B=c("D","E"), stringsAsFactors=FALSE) 
lst2 <- c(X=df3) 

如果數據存儲在列表中,我們可以使用:

lapply(split(c(lst1, lst2), names(c(lst1,lst2))), function(lst) do.call(rbind, lst)) 
0

以下解決方案可能不是最有效的方法。但是,如果我把你的問題就應該工作;)

# Example data 

# Some vectors 
a <- 1:5 
b <- 3:7 
c <- rep(5, 5) 
d <- 5:1 

# Some dataframes, data1 and data3 have identical column names 
data1 <- data.frame(a, b) 
data2 <- data.frame(c, b) 
data3 <- data.frame(a, b) 
data4 <- data.frame(c, d) 

# 2 lists 
list1 <- list(data1, data2) 
list2 <- list(data3, data4) 

# Loop, wich checks for the dataframe names and rbinds dataframes with the same column names 
final_list <- list1 
used_lists <- numeric() 

for(i in 1:length(list1)) { 

    for(j in 1:length(list2)) { 

    if(sum(colnames(list1[[i]]) == colnames(list2[[j]])) == ncol(list1[[i]])) { 

     final_list[[i]] <- rbind(list1[[i]], list2[[j]]) 
     used_lists <- c(used_lists, j) 

    } 
    } 
} 

# Adding the other dataframes, which did not have the same column names 
for(i in 1:length(list2)) { 

    if((i %in% used_lists) == FALSE) { 

    final_list[[length(final_list) + 1]] <- list2[[i]] 

    } 
} 

# Final list, which includes all other lists 
final_list 
+0

感謝您的回覆。不幸的是,在我的示例數據上運行代碼時,我得到以下結果: 'list1 < - lst1 list2 < - lst2 (...) 錯誤if(sum(colnames(list1 [[i]])== colnames(list2 [[j]]))== ncol(list1 [[i]])){: 參數的長度爲零' – RBA

+0

如果您想創建一個數據框列表,您必須寫入列表(df1,df2)而不是c(df1,df2)。如果你這樣做,我的代碼應該工作。 – JSP