2016-11-02 101 views
2

我對創建'會話ID'有類似的問題(Create a "sessionID" based on "userID" and differences in "timeStamp");儘管我的規格略有不同。也許解決方案在這篇文章中仍然很明顯,但我無法將其應用於我的需求 - 指出原始解決方案如何滿足我的問題是等同的。從用戶ID和時間差異創建會話ID

data.table看起來像這樣(dput可用下圖):

unique_visitor_id  datetime    
100     2016-07-25 15:43:02  
100     2016-08-15 15:35:16  
101     2016-08-01 21:24:46  
101     2016-08-13 05:32:27  
101     2016-08-13 05:33:01  
101     2016-08-13 05:33:37  
101     2016-08-13 05:34:04  
101     2016-08-13 05:37:42  
101     2016-08-13 05:38:20  
102     2016-09-15 17:28:00  
102     2016-09-15 17:31:04  
103     2016-07-18 21:19:07 

注:datetimeymd_hms(datetime)

轉換爲lubridate約會對象我想什麼是新的變量識別會話,這是一個簡單的整數序列(不需要包含visitorID,就像原始問題一樣) - 會話由訪問者定義,只要記錄是< = 30m並且在同一個da年。例如,前兩行將是兩個不同的會話:雖然它是同一個訪問者,但時間差異大於30m。從上面的數據

期望的輸出的將是:

unique_visitor_id  datetime   session_id 
100     2016-07-25 15:43:02   1 
100     2016-08-15 15:35:16   2 
101     2016-08-01 21:24:46   3 
101     2016-08-13 05:32:27   4 
101     2016-08-13 05:33:01   4 
101     2016-08-13 05:33:37   4 
101     2016-08-13 05:34:04   4 
101     2016-08-13 05:37:42   4 
101     2016-08-13 05:38:20   4 
102     2016-09-15 17:28:00   5 
102     2016-09-15 17:31:04   5 
103     2016-07-18 21:19:07   6 

如果這可以在data.table的方式來完成,這將是可取的。再次,道歉,如果我失去原來的問題的解決方案!

這裏是dput樣本數據表:

myDT <- structure(list(unique_visitor_id = c(100L, 100L, 101L, 
           101L, 101L, 101L, 101L, 101L, 101L, 102L, 102L, 103L), 
      datetime = structure(c(1469475782, 1471289716, 1470101086, 1471080747, 1471080781, 
              1471080817, 1471080844, 1471081062, 1471081100, 1473974880, 
              1473975064, 1468891147), 
              tzone = "EST5EDT", class = c("POSIXct", "POSIXt"))), 
     .Names = c("unique_visitor_id", "datetime"), 
     sorted = c("unique_visitor_id", "datetime"), 
     class = c("data.table", "data.frame"), 
     row.names = c(NA, -12L)) 

回答

6

假設你的數據幀最初由訪問者ID和日期排序,你可以在其中一個新session_id應該出現這的條件爲真矢量使用cumsum()

myDT[, session_id := cumsum(c(T, diff(unique_visitor_id) != 0 | diff(datetime)/60 > 30))][] 

# unique_visitor_id   datetime session_id 
# 1:    100 2016-07-25 15:43:02   1 
# 2:    100 2016-08-15 15:35:16   2 
# 3:    101 2016-08-01 21:24:46   3 
# 4:    101 2016-08-13 05:32:27   4 
# 5:    101 2016-08-13 05:33:01   4 
# 6:    101 2016-08-13 05:33:37   4 
# 7:    101 2016-08-13 05:34:04   4 
# 8:    101 2016-08-13 05:37:42   4 
# 9:    101 2016-08-13 05:38:20   4 
#10:    102 2016-09-15 17:28:00   5 
#11:    102 2016-09-15 17:31:04   5 
#12:    103 2016-07-18 21:19:07   6 
+1

當事件不在同一天(邊緣情況下),可以很容易地添加一個舞臺,衝擊sID –

+2

工作異常,是@ClaytonStanley,我添加了第三個條件來檢查同一天,30分鐘後檢查:'| diff(date(datetime))!= 0))]' – daRknight

2

與dplyr相同的想法。

library(dplyr) 
library(lubridate) 
myDT %>% 
    mutate(new_session = c(0, diff(datetime)) > 30*60 | 
         c(0, diff(unique_visitor_id)) != 0) %>% 
    mutate(session_id = cumsum(new_session)) %>% print() 

順便說一句,你需要爲新用戶同時添加一個測試用例(這兩個答案都應該覆蓋)。當然,你可以刪除new_session列,我發現它很有幫助。