2016-08-03 12 views
1

Ich habe eine Liste, die eine andere Liste von Datenrahmen haben. Die äußeren Listenelemente stellen Jahre dar und die innere Liste repräsentiert die Daten von Monaten.Liste von Datenrahmen in Liste in bestimmter Weise kombinieren

Jetzt möchte ich eine endgültige Liste erstellen, die Daten für alle Monate enthalten wird. Jeder Monat Spalten werden "cbindiert" durch andere Jahre Spalte Werte.

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))) 

Erwartete Ausgabeliste ist als

folgende

enter image description here

Ich habe versucht for Schleifen und seinen kleinen Komplex verwendet wird, möchte ich jede R-Funktion, diese Aufgabe zu tun.

Ich habe dies mit for-Schleifen mit folgendem Code getan. Aber das ist wirklich komplex und ich selbst fand diese kleine Komplikation. Ich hoffe, dass ich für diese Operation einen einfacheren und sauberen Code bekomme.

I erstellt Liste mit je Monaten und Jahren Daten als ein Listenelement in Form von Datenrahmen

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

Welchen Code haben Sie bisher geschrieben? –

+0

@C_Z_ Bitte lesen Sie die aktualisierte Frage mit meinem Code mit for-Schleifen. –

Antwort

2

Sie den folgenden unten tun könnten. Die lapply iteriert über die äußere Liste und die do.call wird cbind die innere Liste von Datenrahmen.

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 

Sie können auch dplyr verwenden, um die gleichen Ergebnisse zu erhalten.

library(dplyr) 
lapply(Alldata, bind_cols) 

ist die dritte Option von JR vorgeschlagen

lapply(Alldata, Reduce, f = cbind) 

EDIT

Nach der Klärung von OP, die obigen Lösung (siehe unten) zu erzeugen, die neu festgelegten Ausgang modifiziert wurde, . Die obige Lösung wurde dort gelassen, da es sich um einen Baustein für die folgende Lösung handelt.

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

nice, oder 'lapply (Alldata, Reduce, f = cbind)' um eine Reduktion zu betonen. –

+0

@ J.R. Danke für die Alternative. Ich kann es meiner Antwort hinzufügen, wenn Sie nicht vorhaben, es als Antwort, Ihren Anruf, zur Verfügung zu stellen. – steveb

+0

Gehen Sie voran und fügen Sie es hinzu :) –

Verwandte Themen