如何将 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)]
我有一个包含两列 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)]