I have a data.frame with two columns of type POSIXct, though for every row, only one column will have a value, e.g.,
dd <- data.frame(date1 = c(now(), NA), date2 = c(as.POSIXct(NA), now()))
> dd
date1 date2
1 2016-05-06 11:30:04 <NA>
2 <NA> 2016-05-06 11:30:04
I would now like to create a third column that will contain the value of whichever column has a non-NA value, i.e., the result should look like
> dd
date1 date2 date3
1 2016-05-06 11:26:36 <NA> 2016-05-06 11:26:36
2 <NA> 2016-05-06 11:26:36 2016-05-06 11:26:36
I've tried using ifelse(), but it doesn't work:
> mutate(dd, date3 = ifelse(!is.na(date1), date1, date2))
date1 date2 date3
1 2016-05-06 11:30:04 <NA> 1462559405
2 <NA> 2016-05-06 11:30:04 1462559405
Neither does logical vector-based assignment:
> dd[!is.na(dd$date1), "date3"] <- dd[!is.na(dd$date1), "date1"]
> dd[!is.na(dd$date2), "date3"] <- dd[!is.na(dd$date2), "date2"]
> dd
date1 date2 date3
1 2016-05-06 11:30:04 <NA> 1462559405
2 <NA> 2016-05-06 11:30:04 1462559405
Can anyone explain this behavior?
Am I stuck with creating a new data.frame with an empty column of class POSIXct and then assigning into it? This would not be ideal because it breaks the rule of being able to just assign into a data.frame and having it magically work.
Or should I do the assignment and then change the column class afterwards (as suggested in this solution)? This would not be ideal because the conversion to numeric in the course of the assignment drops the timezone, which I would then have to supply again when calling as.POSIXct().
Thanks in advance!
as.POSIXct like so: dd$date3 <- as.POSIXct(ifelse(is.na(dd$date1), dd$date2, dd$date1), origin = origin)
. Also nice:dd[!is.na(dd)]
...but that's column-wise, sot(dd)[!is.na(t(dd))]
, maybe. – alistaireifelse
strips attributes, including classes; see?ifelse
, which has an example very much like yours. The[]
option is more complicated, but is because you're assigning to part (not the whole) of a column that doesn't exist, so coercion takes place to fill the column. There's some info at?`[.data.frame`
, but not much. If you assign something with the appropriate class to the whole column first (e.g.dd$date3 <- as.POSIXct(NA)
) it will work fine. – alistaire