如何将 data.frame 中两个 POSIXct 列之一的值分配给新的 POSIXct 列?

How can I assign the value from one of two POSIXct columns in a data.frame to a new POSIXct column?

我有一个包含两列 POSIXct 类型的 data.frame,但对于每一行,只有一列有一个值,例如

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

我现在想创建第三列,它将包含具有非 NA 值的任何一列的值,即结果应该类似于

> 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 

我试过使用 ifelse(),但它不起作用:

> 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

逻辑向量赋值也不行:

> 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

谁能解释一下这种行为?

我是否坚持创建一个新的 data.frame 并在其空列 class POSIXct 中赋值?这不是理想的,因为它打破了只能分配到 data.frame 并让它神奇地工作的规则。

或者我应该做作业然后更改列 class(如本 solution 中所建议)?这不是理想的,因为在分配过程中转换为数字会丢失时区,然后我必须在调用 as.POSIXct() 时再次提供时区。

提前致谢!

以下解决方案对我有用,尽管它的代码不是很干净:

dd<-read.csv("dd.csv",stringsAsFactors = F,na.strings = c("", " "))

dd[,1]<-as.POSIXct(dd[,1],"%m/%d/%Y %H:%M",tz = "GMT")
dd[,2]<-as.POSIXct(dd[,2],"%m/%d/%Y %H:%M",tz = "GMT")
dd[,'Date3']<-dd[,1]


dd[which(!is.na(dd$Date1)),'Date3']<-dd$Date1[!is.na(dd$Date1)]
dd[which(!is.na(dd$Date2)),'Date3']<-dd$Date2[!is.na(dd$Date2)]

str(dd)
'data.frame':   6 obs. of  3 variables:
 $ Date1: POSIXct, format: "2016-05-20 11:30:00" ...
 $ Date2: POSIXct, format: NA ...
 $ Date3: POSIXct, format: "2016-05-20 11:30:00" .

sum(is.na(dd$Date3))
[1] 0

我使用的技巧是使用 Date1 创建 Date3,这反过来意味着列的 class 是 POSIXct

另一种方法,假设 date1 是 'correct' 然后在适用的地方用 date2 覆盖

dd <- data.frame(date1 = c(now(), NA), date2 = c(as.POSIXct(NA), now()))
dd2 <- dd$date1
dd2[is.na(dd2)]<-dd$date2[is.na(dd2)]