In R, how to prevent the by()
function from changing POSIXct to numeric values automatically?
In the following example, the time
object is class "POSIXct" "POSIXt"
. When using by()
function, the output is numeric
. But when doing what by()
does manually, e.g. min(time[index=='a'])
, the output is still "POSIXct" "POSIXt"
, which is desired. Is there a way to prevent the by()
function from changing POSIXct to numeric values automatically?
time = c("0001-03-04 05:36:00 UTC", "0001-03-04 05:50:00 UTC", "0001-03-04 06:05:00 UTC")
time = as.POSIXct(time, tz = "UTC")
index = c("a", "a", "b")
by(time, index, min) # results are numeric values.
min(time[index=='a']) # "0001-03-04 05:36:00 UTC"
CodePudding user response:
1) Return a list and then concatenate the elements of the result.
do.call("c", by(time, index, function(x) list(min(x))))
## a b
## "0001-03-04 05:36:00 UTC" "0001-03-04 06:05:00 UTC"
2) split/lapply would also work:
do.call("c", lapply(split(time, index), min))
## a b
## "0001-03-04 05:36:00 UTC" "0001-03-04 06:05:00 UTC"
3) as would tapply with simplify = FALSE:
do.call("c", tapply(time, index, min, simplify = FALSE))
## a b
## "0001-03-04 05:36:00 UTC" "0001-03-04 06:05:00 UTC"
4) aggregate can be used.
with(aggregate(time ~., data.frame(time, index), min), setNames(time, index))
## a b
## "0001-03-04 05:36:00 UTC" "0001-03-04 06:05:00 UTC"
or if names are not needed:
aggregate(time, list(index), min)$x
## [1] "0001-03-04 05:36:00 UTC" "0001-03-04 06:05:00 UTC"
or to get a data frame result:
aggregate(time ~., data.frame(time, index), min)
## index time
## 1 a 0001-03-04 05:36:00
## 2 b 0001-03-04 06:05:00