2016-11-06 6 views
0

ich auf SO auf meine frühere Frage bin Gebäude an Pipe output of one data.frame to another using dplyrRohrproduktion von mehr als eine Variable mit tidyr :: Karte oder dplyr

Ich möchte sechs Korrelationsmatrizen schaffen, das würde mir Entwicklung der Korrelation in verbrachte analysieren lassen $ und Menge in den letzten drei Jahren verkauft. Im Wesentlichen suche ich nach 2 X [3X3] Typ Liste. Bis jetzt bin ich in der Lage, 3X3 Liste mit tidyr::map() zu erstellen, indem ich getrennte Anrufe für jede Product_Type und mache, aber ich bin in einem vektorisierten Anruf darin erfolglos gewesen. Wie Sie unten sehen werden, gibt es eine Menge Redundanz in meinem Code.

DFile_Spread_PType <- spread(DFile_Gather[-length(DFile_Gather)],key = Product_Type, value = Mexican_Pesos) 

DFile<-DFile_Spread_PType 
CYear <- unique(DFile$Calendar.Year) 
DFile_Corr_PType <- purrr::map(CYear, ~ dplyr::filter(DFile, Calendar.Year == .)) %>% 
    purrr::map(~ cor(.[,colnames(DFile)[3:length(colnames(DFile))]])) %>% 
    structure(., names = CYear) 

Schließlich, hier ist mein Code für die zweite Iteration für Korrelationsmatrix durch Menge, dh für PRODUCT_TYPE Korrelationsmatrix berechnen:

Hier ist meine Daten:

dput(DFile_Gather) 
structure(list(Order.ID = c(456, 567, 345, 567, 2345, 8910, 8910, 
789, 678, 456, 345, 8910, 234, 1234, 456), Calendar.Year = c(2015, 
2015, 2016, 2015, 2017, 2015, 2015, 2016, 2015, 2015, 2016, 2015, 
2016, 2016, 2015), Product_Type = c("Insurance", "Insurance", 
"Tire", "Tire", "Rental", "Insurance", "Servicing", "Truck", 
"Tire", "Servicing", "Truck", "Rental", "Car", "Servicing", "Tire" 
), Mexican_Pesos = c(35797.32, 1916.25, 19898.62, 0, 22548.314011, 
686.88, 0, 0, 0, 0, 0, 0, 0, 0, 203276.65683), Quantity = c(0.845580721440663, 
0.246177053792905, 2.10266268677851, 1.89588258358317, 0.00223077008050406, 
0.454640961140588, 1.92032156606277, 0.475872861771994, 0.587966920885798, 
0.721024745664671, 0.696609684682582, 0.0441522564791413, 0.872232778060772, 
0.343347997825813, 0.716224049425646)), .Names = c("Order.ID", 
"Calendar.Year", "Product_Type", "Mexican_Pesos", "Quantity"), row.names = c(54L, 
55L, 13L, 15L, 50L, 58L, 28L, 37L, 16L, 24L, 33L, 48L, 2L, 29L, 
14L), class = "data.frame") 

hier für die erste Iteration mein Code ist :

DFile_Spread_Qty <- spread(subset(DFile_Gather, select = -Mexican_Pesos),key = Product_Type, value = Quantity) 
DFile<-DFile_Spread_Qty 
DFile_Corr_Qty <- purrr::map(CYear, ~ dplyr::filter(DFile, Calendar.Year == .)) %>% 
    purrr::map(~ cor(.[,colnames(DFile)[3:length(colnames(DFile))]])) %>% 
    structure(., names = CYear) 

Wie Sie oben sehen können, gibt es auch m uch Redundanz, und der Code sieht wirklich klobig aus. Ich würde mich sehr freuen, wenn mir jemand helfen könnte. Ich bin speziell für zwei Dinge suchen:

1) tun, was ich oben tue von nicht

2) Wenn möglich, jede Redundanz aufweist, erhält eine Liste von 2x3x3 dh Quantity und Product_Type auf höchster Ebene, und dann 3x3 Korrelationsmatrizen, auf die jeweils Bezug genommen wird.

Ich suchte ähnliche Themen auf SO, aber ich glaube nicht, es gab einen Thread zu ähnlichen Themen.

Vielen Dank im Voraus.

Antwort

1

Das Folgende hat keine Redundanz und verwendet keine Pakete. Machen Sie Product_Type einen Faktor und teilen Sie dann nach Jahr die Liste der Jahre s. Verwenden Sie jetzt eine doppelte Map über s und Values konvertieren in breite Form auf jeder inneren Iteration mit tapply und cor ausgeführt.

DG <- transform(DFile_Gather, Product_Type = factor(Product_Type)) 
s <- split(DG, DG$Calendar.Year) 
Values <- c("Mexican_Pesos", "Quantity") 
By <- c("Order.ID", "Product_Type") 
res <- Map(function(v) Map(function(s) cor(tapply(s[, v], s[By], c)), s), Values) 
+0

@G Grothendieck - Vielen Dank für Ihre Hilfe. Dies löst das Problem. Sehr respektvoll, meinst du, du könntest die letzte Zeile etwas entmystifizieren? Ich habe versucht, zu verstehen, was Sie getan haben, indem ich die Aussage in Teilen ausgeführt habe, aber ich bekomme alle Arten von gottlosen Fehlern, von denen ich nicht glaube, dass ich jemals in der Lage sein werde, sie zu verstehen. Ich würde mich freuen, wenn Sie die letzte Aussage erklären könnten, indem Sie sie in ausführbare Teile zerlegen, die auf unserer Maschine laufen könnten, weil sie wirklich mächtig ist, und wenn sie richtig verstanden wird, wird sie mir in der Zukunft sehr helfen. – watchtower

+1

'tapply (s [, v], v [Von], c)' wandelt 'Mexican_Pesos' oder' Quantity' (abhängig vom Wert von 'v') für ein Jahr Daten (abhängig von' s') in Wide um Form so, dass die Wide Form Zeilen durch 'By [1]' definiert sind, dh durch 'Order.ID' und die Spalten durch' By [2] ', dh durch' Product_Type'. Wir nehmen das "cor" davon. Das "cor (tapply (...))" kann als der Körper einer doppelten Schleife betrachtet werden, die über alle Kombinationen von 's' und' Values' iteriert. –

1

Um die Korrelationen zwischen Product_Type für jede Antwortvariable und Jahr Kombination zu erhalten, können Sie Ihre Daten-Set in einem handlichen Format umformen könnte, teilen Sie den Datensatz in eine Liste für die Kombination von Faktoren ab, und die Korrelationen erhalten über map mit die Hilfe von dplyr::select für die Auswahl der Spalten. Dies gibt jedoch keine Liste von Listen zurück.

library(purrr) 
library(tidyr) 

DFile_Gather %>% 
    gather(type, value, Mexican_Pesos:Quantity) %>% 
    spread(Product_Type, value) %>% 
    split(list(.$Calendar.Year, .$type)) %>% 
    map(~cor(dplyr::select(.x, Car:Truck))) 

Die Liste der Listen nahm einen zusätzlichen Schritt, wie ich durch die Antwortvariable ersten split hatte und dann in jedem Element dieser Liste, split von Calendar.Year. Dann habe ich at_depth anstelle von map verwendet, um die Korrelationen über Product_Type für jede Liste in der Liste zu berechnen. Arbeiten auf der niedrigsten Stufe wird durch die 2 in at_depth angezeigt.

DFile_Gather %>% 
    gather(type, value, Mexican_Pesos:Quantity) %>% 
    spread(Product_Type, value) %>% 
    split(.$type) %>% 
    map(~split(.x, .x$Calendar.Year)) %>% 
    at_depth(2, ~cor(dplyr::select(.x, Car:Truck))) 

Die ersten paar Zeilen/Spalten des Zwischendatensatzes nach dem Sammeln und Verbreitung sieht aus wie:

Order.ID Calendar.Year   type  Car Insurance  Rental 
1  234   2016 Mexican_Pesos 0.0000000   NA   NA 
2  234   2016  Quantity 0.8722328   NA   NA 
3  345   2016 Mexican_Pesos  NA   NA   NA 
4  345   2016  Quantity  NA   NA   NA 
5  456   2015 Mexican_Pesos  NA 3.579732e+04   NA 
6  456   2015  Quantity  NA 8.455807e-01   NA 
... 
Verwandte Themen