Trying to figure this out. Suppose you have a data.table:
dt <- data.table (person=c('bob', 'bob', 'bob'),
door=c('front door', 'front door', 'front door'),
type=c('timeIn', 'timeIn', 'timeOut'),
time=c(
as.POSIXct('2016 12 02 06 05 01', format = '%Y %m %d %H %M %S'),
as.POSIXct('2016 12 02 06 05 02', format = '%Y %m %d %H %M %S'),
as.POSIXct('2016 12 02 06 05 03', format = '%Y %m %d %H %M %S') )
)
I want to pivot it to look like this
person door timeIn timeOut
bob front door min(<date/time>) max(<date/time>)
I can't seem to get the right syntax for dcast.data.table. I tried
dcast.data.table(
dt, person + door ~ type,
value.var = 'time',
fun.aggregate = function(x) ifelse(type == 'timeIn', min(x), max(x))
)
which throws an error:
Aggregating function(s) should take vector inputs and return a single value (length=1).
I also tried:
dcast.data.table(dt, person + door ~ type, value.var = 'time')
But the result throws away my dates
person door timeIn timeOut
1: bob front door 2 1
Any suggestions would be appreciated. TIA
There are several ways to achieve the desired result using
dcast. jazzurro's solution does the aggregation before reshaping the result. The approaches here usedcastdirectly but may require some post-processing. We are using jazzurro's data which are tweaked to obey theUTCtime zone and CRAN version 1.10.0 ofdata.table.1. Getting
ifelseto workAs reported in the Q,
returns an error message. The full text of the error message includes the hint to use the
fillparameter. Unfortunately,ifelse()doesn't respect thePOSIXctclass (for details see?ifelse) so this needs to be enforced.With
we do get
2. Alternative to
ifelseifelse's help page suggestsas alternative. Following this advice,
returns
Note that neither the
fillparameter nor the coercion toPOSIXctis needed.3. Using enhanced
dcastWith the latest versions of
dcast.data.tablewe can provide a list of functions tofun.aggregate:returns
We can remove the unwanted columns and rename the others by
which gets us
Data
As mentioned above, we are using jazzurro's data
but coerce the time zone to
UTC.With
we have
independent of local time zone.