Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>One solution is to first split the intervals, so that they are sometimes equal but never partially overlap, and them remove the duplicates. The problem is that we are left with many small abutting intervals, and merging them does not look straightforward.</p> <pre><code>library(reshape2) library(sqldf) d$machine &lt;- as.character( d$machine ) # Duplicated levels... ddply( d, c("username", "machine"), function (u) { # For each username and machine, # compute all the possible non-overlapping intervals intervals &lt;- sort(unique( c(u$start, u$end) )) intervals &lt;- data.frame( start = intervals[-length(intervals)], end = intervals[-1] ) # Only retain those actually in the data u &lt;- sqldf( " SELECT DISTINCT u.username, u.machine, intervals.start, intervals.end FROM u, intervals WHERE u.start &lt;= intervals.start AND intervals.end &lt;= u.end " ) # We have non-overlapping, but potentially abutting intervals: # ideally, we should merge them, but I do not see an easy # way to do so. u } ) </code></pre> <p><strong>EDIT:</strong> Another, conceptually cleaner solution, that fixes the non-merged abutting intervals problem, is to count the number of open sessions for each user and machine: when it stops being zero, the user has logged in (with one or more session), when it drops to zero, the user has closed all his/her sessions.</p> <pre><code>ddply( d, c("username", "machine"), function (u) { a &lt;- rbind( data.frame( time = min(u$start) - 1, sessions = 0 ), data.frame( time = u$start, sessions = 1 ), data.frame( time = u$end, sessions = -1 ) ) a &lt;- a[ order(a$time), ] a$sessions &lt;- cumsum(a$sessions) a$previous &lt;- c( 0, a$sessions[ - nrow(a) ] ) a &lt;- a[ a$previous == 0 &amp; a$sessions &gt; 0 | a$previous &gt; 0 &amp; a$sessions == 0, ] a$previous_time &lt;- a$time a$previous_time[-1] &lt;- a$time[ -nrow(a) ] a &lt;- a[ a$previous &gt; 0 &amp; a$sessions == 0, ] a &lt;- data.frame( username = u$username[1], machine = u$machine[1], start = a$previous_time, end = a$time ) a } ) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload