2016-09-30 7 views
2

Ich habe zwei Tabellen in R, die wie folgt aussehen:Optimierung von Data.Table in R?

DT.Purchase <- data.frame(ID = c(1,1,1,2,2,3,3,3,3,3,4,4,4,4), 
          CDS = c("0389","0389", "3298", "4545", "1282", "4545", 
            "0389","0389", "5685", "4545", "1282", "0389", 
            "1282", "1282") 
         Date = c("5/28/2016","5/26/2016","8/9/2016","2/2/2015", 
            "2/24/2015", "9/27/2015", "9/27/2015", "9/5/2015", 
            "3/3/2016", "4/9/2014", "5/1/2014", "5/4/2014", 
            "6/9/2014", "7/7/2014"), 
          JFK = c(T,F,F,F,T,T,F,F,T,F,T,T,T,F), 
          RFK = c(F,T,T,F,T,F,F,F,F,T,T,T,T,T), 
          RUG = c(T,F,T,F,T,F,F,F,F,T,F,F,T,T), 
          LPG = c(T,T,T,F,F,T,T,F,F,F,F,F,T,F)) 


DT.Purchase$Date <- as.Date(DT.Purchase$Date, format = "%m/%d/%Y") 
DT.Purchase  <- data.table(DT.Purchase) 
ID CDS  Date JFK RFK RUG LPG 
1 0389 5/28/2016 T F T T 
1 0389 5/26/2016 F T F T 
1 3298 8/9/2016 F T T T 
2 4545 2/2/2015 F F F F 
2 1282 2/24/2015 T T T F 
3 4545 9/27/2015 T F F T 
3 0389 9/27/2015 F F F T 
3 0389 9/5/2015 F F F F 
3 5685 3/3/2016 T F F F 
3 4545 4/9/2014 F T T F 
4 1282 5/1/2014 T T F F 
4 0389 5/4/2014 T T F F 
4 1282 6/9/2014 T T T T 
4 1282 7/7/2014 F T T F 

DT.Stay <- data.frame(Stay.ID = c(1,2,3,5,6,9,10,11), 
          ID = c(1,1,2,3,3,3,4,4), 
        Start.Date = c('5/26/2016','8/1/2016', '2/1/2015', '3/1/2016', 
            '9/1/2015', '4/9/2014', '4/7/2014','6/1/2014'), 
        End.Date = c('6/6/2016','9/1/2016','3/1/2015','3/7/2016', 
            '9/30/2015','4/14/2014','5/9/2014','7/11/2014')) 
DT.Stay$Start.Date <- as.Date(DT.Stay$Start.Date, format = "%m/%d/%Y") 
DT.Stay$End.Date <- as.Date(DT.Stay$End.Date, format = "%m/%d/%Y") 

DT.Stay <- data.table(DT.Stay) 

Stay.ID ID Start.Date End.Date 
1 1 5/26/2016 6/6/2016 
2 1 8/1/2016 9/1/2016 
3 2 2/1/2015 3/1/2015 
5 3 3/1/2016 3/7/2016 
6 3 9/1/2015 9/30/2015 
9 3 4/9/2014 4/14/2014 
10 4 4/7/2014 5/9/2014 
11 4 6/1/2014 7/11/2014 

nun in Wirklichkeit DT.Purchase viel größer ist (10 Millionen Beobachtungen) und DT.Stay ist über 50000 Beobachtungen. Es gibt Gewichte für DT.Purchase[ ,.(JFK, RFK, DUG, LPG)], was c.weights = c(1,2,1,3) entspricht. Diese Gewichte stellen ein internes Kostengewicht dar, das wir in Betracht ziehen. Ziel ist es, Einkaufsabschlüsse basierend auf vorherigen Einkäufen und Gewichten zu ermitteln. Was ich tun möchte, ist die vorherige cost.index, die die Summe aller früheren Einkäufe auf der Grundlage der Gewichte und vor jedem End.Date für jeden Stay.ID ist. So ist die letzte data.table wie

aussehen sollte
Stay.ID cost.index 
1  10 
2  16 
3  4 
5  11 
6  10 
9  3 
10  6 
11  10 

So wie ich dies getan haben, geht nach ID Verschmelzung (allow.cartesian = TRUE) die beiden Datensätze und überprüft, ob Date <= End.Date zu sehen. Dann ersetze ich die Gewichte in und sum für jeden Stay.ID. Es funktioniert, aber ich suche nach einem schnelleren Weg, dies zu tun. Mit 10 Millionen und 50000 Beobachtungen wird die Verschmelzung zeit- und ressourcenintensiv.

+4

Bitte Code zeigen und bieten Datensätze in einem ladbaren Format – HubertL

+0

By the way, haben Sie eine harte Zeit, die Dinge effizient zu nutzen ersatz Speicher tun Formate. R unterstützt eine 'Date'-Klasse und eine' logische' Klasse (mit TRUE- und FALSE-Werten). – Frank

Antwort

5

Mit der neuesten Version devel (1.9.7+), smth wie dies funktionieren wird:

DT.Purchase[DT.Stay, on = .(ID = ID, Date >= Start.Date, Date <= End.Date), 
      .(Stay.ID, sum(as.matrix(.SD) %*% c.weights)), 
      by = .EACHI, .SDcols = JFK:LPG] 

Ihre Reisedaten in beide Date oder IDate Format Unter der Annahme.

In 1.9.6 Sie foverlaps stattdessen verwenden können:

foverlaps(setkey(DT.Purchase[, Date2 := Date], ID, Date, Date2), 
      setkey(DT.Stay, ID, Start.Date, End.Date))[, 
    sum(as.matrix(.SD) %*% c.weights), keyby = Stay.ID, .SDcols = JFK:LPG] 
+0

Ich habe keinen Zugriff auf 1.9.7, weil Sie es von Github herunterladen müssen. Kennen Sie 1.9.6 Lösungen? – akash87

+0

@ akash87 hinzugefügt eine 1.9.6 Antwort (die ursprüngliche Reihenfolge verlieren wird, also wenn Sie das brauchen - müssen Sie einen separaten Index hinzufügen, um es wiederherzustellen) – eddi

+0

@ akash87 haben Sie die [Installationsanweisungen] gelesen (https://github.com/Rdatatable/data.table/wiki/Installation)? Devel auf GitHub sollte kein Hindernis sein _per se_ – MichaelChirico