jlesuffleur - 6 months ago 53

R Question

I am trying to find the row-wise minimum from a data frame of

`POSIXct`

`apply`

`which.min`

`df <- data.frame(date1 = as.POSIXct(c("2016-01-01", "2016-02-01")),`

date2 = as.POSIXct(c("2015-10-01", "2016-06-01")))

apply(df, 1, which.min) # not OK

# integer(0)

# Warning messages:

# 1: In FUN(newX[, i], ...) : NAs introduced by coercion

# 2: In FUN(newX[, i], ...) : NAs introduced by coercion

apply(df, 1, function(x) which(x == min(x))) # OK

# [1] 2 1

sapply(1:nrow(df), function(i) which.min(df[i,])) # OK

# date2 date1

# 2 1

Can anybody explain this behaviour?

Thanks !

Answer

Look at this:

```
str(apply(df, 1, identity))
# chr [1:2, 1:2] "2016-01-01" "2015-10-01" "2016-02-01" "2016-06-01"
# - attr(*, "dimnames")=List of 2
# ..$ : chr [1:2] "date1" "date2"
# ..$ : NULL
```

Applying `identity`

turns the POSIXct values into characters! This happens because `apply`

coerces its input into a matrix and `as.matrix.data.frame`

uses `format`

on POSIXct values because a matrix can only hold atomic values and S3 objects like POSIXct are not atomic. Thus the resulting matrix is a character matrix. And you can't calculate the minimum of characters. `sapply`

iterates over its input and doesn't turn the data.frame into a matrix.