Finding time differences of requested pair of pages in a web access session

Viewed 41

I have this subset of a dataframe

lf = structure(list(session_id = c(48L, 48L, 48L, 48L, 48L, 48L, 54L, 
54L, 54L, 54L, 54L, 54L, 72L, 72L, 72L, 72L, 72L, 74L, 74L, 74L, 
74L, 74L, 78L, 78L, 78L, 78L, 78L, 90L, 90L, 90L), datetime = structure(c(1457050110, 
1457050111, 1457050112, 1457050114, 1457050117, 1457050118, 1457052045, 
1457052048, 1457052050, 1457052051, 1457052052, 1457052054, 1457057067, 
1457057067, 1457057067, 1457057070, 1457057071, 1457058143, 1457058143, 
1457058144, 1457058149, 1457058150, 1457059193, 1457059193, 1457059195, 
1457059198, 1457059199, 1457063485, 1457063486, 1457063486), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), request = c(7, 7, 14, 20, 9, 4, 9, 
1, 12, 20, 6, 12, 4, 15, 8, 8, 12, 10, 6, 6, 13, 1, 5, 6, 20, 
1, 8, 3, 6, 13)), .Names = c("session_id", "datetime", "request"
), row.names = c(NA, -30L), class = c("grouped_df", "tbl_df", 
"tbl", "data.frame"))

Now i want to write a function which will take a pair of request (request1,request2) as input and produce an output as i am uploading a desired output pic

I have used this code but stucked in finding time diff w.r.t positional indexes :-

lf1 = lf %>% group_by(session_id) %>% do(positions = match(c(1,6),.$request),session_duration = max(.$datetime)-min(.$datetime)) 

As you see i took an instance of request pair (1,6) in above code but want to write a function doing the work

Desired output :- enter image description here

1 Answers

In the given scenario, you don't have to worry about explicit positions. The considers only the (a) range within a sessions and (b) if both boundaries are met within a session.

Also, watch out for tibbles that are accidentally left as grouped. I try to always ungroup() them before the pipe/chain concludes.

lf <- lf %>% 
  dplyr::ungroup()

lf %>% 
  dplyr::filter(request %in% c(1, 6)) %>%
  dplyr::group_by(session_id) %>% 
  dplyr::summarize(
    has_both_boundaries = (any(request==1) & any(request==6)),
    session_duration    = as.integer(difftime(max(datetime), min(datetime), units="secs"))
  ) %>% 
  dplyr::ungroup() %>% 
  dplyr::filter(has_both_boundaries) %>%
  dplyr::select(-has_both_boundaries) %>% 
  dplyr::right_join(
    lf %>% 
      dplyr::distinct(session_id),
    by = "session_id"
  )

Produces:

# A tibble: 6 x 2
  session_id session_duration
       <int>            <int>
1         48               NA
2         54                4
3         72               NA
4         74                7
5         78                5
6         90               NA

Do you need those empty rows for sessions 48, 72, & 90? If not, omit that concluding right_join() clause.

Related