2016-08-03 40 views
1

我得到一個列表,其中有另一個數據幀列表。 外部列表元素代表年份,內部列表代表月份數據。以特定的方式組合列表中的數據幀列表

現在我想創建一個包含所有月份數據的最終列表。每個月的列將由其他年份的列值「結合」。

Alldata <- list() 

Alldata[[1]] <- list(data.frame(Jan_2015_A=c(1,2), Jan_2015_B=c(3,4)), data.frame(Feb_2015_C=c(5,6), Feb_2015_D=c(7,8))) 
Alldata[[2]] <- list(data.frame(Jan_2016_A=c(1,2), Jan_2016_B=c(3,4)), data.frame(Feb_2016_C=c(5,6), Feb_2016_D=c(7,8))) 

預期的輸出情況如下表所示

enter image description here

我使用for循環和它的小複雜試過,我想任何一個R函數做這個任務。

我已經完成了使用for循環使用下面的代碼。但是這非常複雜,我自己發現這個有點複雜。希望我會得到這個操作的任何簡單和整潔的代碼。

我創建了每幾個月和幾年的數據作爲數據形式的列表項列表框

x2 <- list() 

for(l1 in 1: length(Alldata[[1]])){ 
    temp <- list() 
    for(l2 in 1: length(Alldata)){ 


    temp <- append(temp, list(Alldata[[l2]][[l1]])) 

    } 

    x2 <- append(x2, list(temp)) 
} 

# then created final List with succesive years data of each month as list items. This is primarily used for Tracking data for years For Example: how much was count was for Jan_2015 and Jan_2016 for "A" 
finalList <- list() 
for(l3 in 1: length(x2)){ 

    temp <- x2[[l3]] 
    td2 <- as.data.frame(matrix("", nrow = nrow(temp[[1]]))) 
    rownames(td2)[rownames(temp[[1]])!=""] <- rownames(temp[[1]])[rownames(temp[[1]])!=""] 
    for(l4 in 1:ncol(temp[[1]])){ 
    for(l5 in 1: length(temp)){ 

     # lapply(l4, function(x) do.call(cbind, 
     td2 <- cbind(td2, temp[[l5]][, l4, drop=F]) 
    } 

    } 

    finalList <- append(finalList, list(td2)) 

} 

> finalList 
[[1]] 
    V1 Jan_2015_A Jan_2016_A Jan_2015_B Jan_2016_B 
1    1   1   3   3 
2    2   2   4   4 

[[2]] 
    V1 Feb_2015_C Feb_2016_C Feb_2015_D Feb_2016_D 
1    5   5   7   7 
2    6   6   8   8 
+0

你到目前爲止寫了哪些代碼? –

+0

@C_Z_請使用for循環查看我的代碼更新後的問題。 –

回答

2

你可以做下面的下面。 lapply將迭代外部列表,並且do.callcbind數據幀的內部列表。

lapply(Alldata, do.call, what = 'cbind') 
[[1]] 
    Jan_2015_A Jan_2015_B Feb_2015_C Feb_2015_D 
1   1   3   5   7 
2   2   4   6   8 

[[2]] 
    Jan_2016_A Jan_2016_B Feb_2016_C Feb_2016_D 
1   1   3   5   7 
2   2   4   6   8 

您也可以使用dplyr獲得相同的結果。

library(dplyr) 
lapply(Alldata, bind_cols) 

這裏是產生新指定的輸出由JR提出了第三個選項

lapply(Alldata, Reduce, f = cbind) 

EDIT

澄清從OP後,將上述溶液已被修改(見下文) 。上面的解決方案已經存在,因爲它是以下解決方案的構建塊。

pattern.vec <- c("Jan", "Feb") 
### For a given vector of months/patterns, returns a 
### list of elements with only that month. 
mon_data <- function(mo) { 
    return(bind_cols(sapply(Alldata, function(x) { x[grep(pattern = mo, x)]}))) 
} 
### Loop through months/patterns. 
finalList <- lapply(pattern.vec, mon_data) 
finalList 

## [[1]] 
## Jan_2015_A Jan_2015_B Jan_2016_A Jan_2016_B 
## 1   1   3   1   3 
## 2   2   4   2   4 
## 
## [[2]] 
## Feb_2015_C Feb_2015_D Feb_2016_C Feb_2016_D 
## 1   5   7   5   7 
## 2   6   8   6   8 

## Ordering the columns as specified in the original question. 
## sorting is by the last character in the column name (A or B) 
## and then the year. 
lapply(finalList, function(x) x[ order(gsub('[^_]+_([^_]+)_(.*)', '\\2_\\1', colnames(x))) ]) 
## [[1]] 
## Jan_2015_A Jan_2016_A Jan_2015_B Jan_2016_B 
## 1   1   1   3   3 
## 2   2   2   4   4 
## 
## [[2]] 
## Feb_2015_C Feb_2016_C Feb_2015_D Feb_2016_D 
## 1   5   5   7   7 
## 2   6   6   8   8 
+1

好,或者'lapply(Alldata,Reduce,f = cbind)'強調減少。 –

+0

@ J.R。感謝您的選擇。如果您不打算將它作爲答案,您的電話,我可以將其添加到我的答案中。 – steveb

+0

繼續並添加它:) –