2015-08-08 7 views
5

Sto tentando di convertire il codice SQL in codice R. Tuttavia, i dati sono circa 35 milioni di record con 200 colonne ciascuno. Quindi la scelta migliore che ho trovato è il pacchetto data.table.Conversione del codice `caso quando ...` di SQL utilizzando il pacchetto data.table in R

Ecco il problema. Nel codice SQL sono in grado di eseguire un'operazione di questo tipo,

select order_date,sum(case when item in ("D","C","B") then col4 end)as col1 
sum(case when item not in ("Z","X","Y") then col4 end) as col2 
from datatable 
where col3 <25 
group by order_date; 

Qual query precedente mi permette di gruppo per ogni data. Non riesco a duplicarlo in data.table. I miei tentativi sono i seguenti.

grp1<- c("D","C","B") 
grp2<- c("Z","X","Y") 
d1 <- dat[item %in% grp1,.(col1 = sum(col4,na.rm = TRUE),by = Order_Date] 
d2 <- dat[item %in% grp2,.(col2 = sum(col4,na.rm = TRUE),by = Order_Date] 
d3 <- data.table(d1,d2) 

Ora, dal momento che subsets inizialmente il mio raggruppamento è diverso sia d1 e d2

+0

So che questa non è una tua domanda, ma sai che esistono pacchetti R che sono in grado di eseguire codice SQL (dplyr e altri)? – maj

+0

Non capisco quando dici, non la mia domanda? Desidero implementare tutto ciò utilizzando il pacchetto data.table. – Shoaibkhanz

+0

Sono interessante nel timing delle soluzioni SQL e R sui tuoi dati (35Mx200), potresti controllarlo e pubblicarlo? – jangorecki

risposta

6

Si può provare la seguente:

DT[col3 < 25, 
    .(col1 = sum(col4[item %in% c("D","C","B")]), 
    col2 = sum(col4[!item %in% c("Z","X","Y")])), 
    by = .(order_date)] 
0
>  d <- " 
+  order_date,item,col4,col3 
+  2000-01-01,D,1,10 
+  2000-01-01,C,1,10 
+  2000-01-01,M,1,10 
+  2000-01-01,N,1,50 
+  2000-01-01,Z,1,10 
+  2000-01-01,X,1,10 
+  2001-01-02,Z,1,0 
+  2001-01-02,X,1,50" 
> 
>  df = read.csv(textConnection(d)) 
> 
>  # data.frame + plyr approach 
> 
>  require(plyr) 
Loading required package: plyr 
>  ddply(
+  df[df$col3<25,], 
+  .(order_date), 
+  summarize, 
+  col1=sum(item %in% c("D","C","B") & col4), 
+  col2=sum(!item %in% c("Z","X","Y") & col4) 
+ ) 
     order_date col1 col2 
1  2000-01-01 2 3 
2  2001-01-02 0 0 
> 
>  # data.table approach, thanks to jangorecki 
> 
>  require(data.table) 
Loading required package: data.table 
>  dt = data.table(df) 
> 
>  dt[col3 < 25, 
+  .(col1 = sum(col4[item %in% c("D","C","B")]), 
+   col2 = sum(col4[!item %in% c("Z","X","Y")])), 
+  by = .(order_date)] 
     order_date col1 col2 
1:  2000-01-01 2 3 
2:  2001-01-02 0 0 
>