2017-09-28 2 views
0

Ich habe mem_ord (1561464ods von 74 Variablen). SITE_JOIN_DATE ist der Datumstyp und SITE_JOIN_DATE versucht, den Benutzertyp entsprechend der Bedingung zu teilen. Aber es war zu langsam, um die Ergebnisse zu sehen. Die if-Bedingung ist zu langsam. Wie kann ich die Geschwindigkeit erhöhen? Ich kann auch mehrere Kerne verwenden.beschleunigen, wenn Aussage in Datentabelle auf r

mem_ord_by_user <- mem_ord[, list(
     AF_SITE_JOIN_DT = Sys.Date() - SITE_JOIN_DATE, 
     DAY_PAY_CNT = .N, 
     DAY_TOT_PRICE = .SD[, sum(TOT_PAY_PRICE)], 
     USER_TYPE = .SD[ 
     ,if(SITE_JOIN_DATE > '2017-07-17' && SITE_JOIN_DATE < '2017-08-05' && !is.na(SITE_JOIN_DATE)){ 
      'event_joiner' 
     }else if((SITE_JOIN_DATE <= '2017-07-17' || SITE_JOIN_DATE >= '2017-08-05') && !is.na(SITE_JOIN_DATE)){ 
      'no_event_joiner' 
     }else{ 
      'null_user' 
     }] 
    ), 
    by=list(ORD_DT, CUSTOMER_NUM), 
    .SDcols = c('TOT_PAY_PRICE', 'SITE_JOIN_DATE')] 
+0

Der Schlüsselwert in mem_ord ist setkeyv (mem_ord, c ('ORD_DT', 'CUSTOMER_NUM')). Dies kann auch geändert werden. –

+0

können Sie Beispieldaten angeben? – minem

+0

Wäre es ein schneller Unterschied, wenn Sie ein verschachteltes 'ifelse()' Konstrukt anstelle von 'if() ... verwenden würden, wenn if() '? – LAP

Antwort

0

Wollen Sie so etwas?

require(data.table) 
N <- 10 
dateSeq <- seq(as.Date('2017/07/01'), Sys.Date(), by="day") 
set.seed(120) 
mem_ord <- data.table(SITE_JOIN_DATE = sample(dateSeq, N, replace=T), 
         TOT_PAY_PRICE = rnorm(N), 
         ORD_DT = sample(dateSeq, N, replace=T), 
         CUSTOMER_NUM = sample(1:1000, N, replace=T)) 

mem_ord[sample(1:.N, 2), SITE_JOIN_DATE := NA] 
mem_ord 
# SITE_JOIN_DATE TOT_PAY_PRICE  ORD_DT CUSTOMER_NUM 
# 1:  2017-08-05 0.22596353 2017-07-14   975 
# 2:   <NA> -0.90504565 2017-08-17   124 
# 3:  2017-08-01 1.70870936 2017-09-25   382 
# 4:  2017-09-10 0.09849052 2017-09-22   890 
# 5:  2017-07-18 0.79617909 2017-08-02   499 
# 6:   <NA> 0.38020124 2017-08-06   902 
# 7:  2017-09-27 0.46077825 2017-09-09   367 
# 8:  2017-07-09 0.49886281 2017-08-08   907 
# 9:  2017-09-15 -1.35021861 2017-07-18   906 
# 10:  2017-09-21 -0.53256174 2017-09-01   560 

d1 <- as.Date('2017-07-17') 
d2 <- as.Date('2017-08-05') 
mem_ord[, USER_TYPE := ifelse(SITE_JOIN_DATE > d1 & SITE_JOIN_DATE < d2, 
           "event_joiner", "no_event_joiner")] 
mem_ord[is.na(USER_TYPE), USER_TYPE := "null_user"] 
mem_ord[, .N ,keyby = USER_TYPE] 
#   USER_TYPE N 
# 1: event_joiner 2 
# 2: no_event_joiner 6 
# 3:  null_user 2 

mem_ord_by_user <- mem_ord[, list(
    AF_SITE_JOIN_DT = Sys.Date() - SITE_JOIN_DATE, 
    DAY_PAY_CNT = .N, 
    DAY_TOT_PRICE = sum(TOT_PAY_PRICE), 
    USER_TYPE = USER_TYPE), 
by=list(ORD_DT, CUSTOMER_NUM, SITE_JOIN_DATE)] 

mem_ord_by_user 
# ORD_DT CUSTOMER_NUM SITE_JOIN_DATE AF_SITE_JOIN_DT DAY_PAY_CNT DAY_TOT_PRICE  USER_TYPE 
# 1: 2017-07-14   975  2017-08-05   54 days   1 0.22596353 no_event_joiner 
# 2: 2017-08-17   124   <NA>   NA days   1 -0.90504565  null_user 
# 3: 2017-09-25   382  2017-08-01   58 days   1 1.70870936 event_joiner 
# 4: 2017-09-22   890  2017-09-10   18 days   1 0.09849052 no_event_joiner 
# 5: 2017-08-02   499  2017-07-18   72 days   1 0.79617909 event_joiner 
# 6: 2017-08-06   902   <NA>   NA days   1 0.38020124  null_user 
# 7: 2017-09-09   367  2017-09-27   1 days   1 0.46077825 no_event_joiner 
# 8: 2017-08-08   907  2017-07-09   81 days   1 0.49886281 no_event_joiner 
# 9: 2017-07-18   906  2017-09-15   13 days   1 -1.35021861 no_event_joiner 
10: 2017-09-01   560  2017-09-21   7 days   1 -0.53256174 no_event_joiner 
+0

Danke. Ich war besorgt über die Methode: = in der Datentabelle, aber ich wusste nicht, was ich tun sollte. Wie Sie oben sehen können, ist die Geschwindigkeit viel schneller. –