日期只是 lapply 之后的一个数字

Date just a number after lapply

我有一个要更改的日期向量。但在 lapply 之后,日期会出现双重行为。

DF<- data.frame(col1=c(1, 2, 3), time=strptime(c("12:01", "12:02", "12:03"), format="%H:%M"))
t<-DF$time
t<-lapply(t, function(x){if (x> strptime("12:02",format="%H:%M") ){x - (24*3600)}else{x}})
DF$time<-t
DF
#  col1    time
#1    1 1.4e+09
#2    2 1.4e+09
#3    3 1.4e+09

如果我查看 DF$time,我会得到

DF$time
#[[1]]
#[1] "2015-11-09 12:01:00 CET"
#
#[[2]]
#[1] "2015-11-09 12:02:00 CET"
#
#[[3]]
#[1] "2015-11-08 12:03:00 CET"

但特别是对于绘图,日期只是数字。 (with(DF, plot(col1,time, type="b")))

base R 正如 Roland 所建议的,这可以在 base with

中完成
# op's example data
DF <- data.frame(col1=c(1,2,3), time=strptime(c("12:01","12:02","12:03"),format="%H:%M"))

# one-liner:
DF$time[DF$time > strptime("12:02",format="%H:%M")] <- 
DF$time[DF$time > strptime("12:02",format="%H:%M")] - 24*3600

# or, a longer option:
DF$time <- replace(
  DF$time, 
  DF$time > strptime("12:02",format="%H:%M"), 
  DF$time[DF$time > strptime("12:02",format="%H:%M")] - 24*3600
)

当我们像这样修改向量的一部分时,列 (POSIXct) 的 class 被保留。

# 'data.frame':   3 obs. of  2 variables:
#  $ col1: num  1 2 3
#  $ time: POSIXct, format: "2015-11-09 12:01:00" "2015-11-09 12:02:00" "2015-11-08 12:03:00"

使用 lapply 和相关函数,保留 class 很难:

Lres  <- lapply(DF$time, function(x) if (x > strptime("12:02",format="%H:%M")  ) x - (24*3600) else x)
class(Lres)  # list 

uLres <- unlist(Lres)
class(uLres) # numeric 

Sres  <- sapply(DF$time, function(x) if (x > strptime("12:02",format="%H:%M")  ) x - (24*3600) else x)
class(Sres)  # numeric

此行为记录在 help("lapply") 的 "Value" 部分:lapply 给出了一个列表,sapply 给出了一个带有原子 类(不包括 POSIXct)如果可以的话。


data.table 我会使用 data.table,它有很好的语法来改变向量的一部分:

library(data.table)
DF <- data.frame(col1=c(1,2,3), time=strptime(c("12:01","12:02","12:03"),format="%H:%M"))

setDT(DF)[ time > strptime("12:02",format="%H:%M"), time := time - 24*3600 ]

data.table 整数格式 该软件包也有单独的日期和时间格式:

DF <- data.frame(col1=c(1,2,3), time=strptime(c("12:01","12:02","12:03"),format="%H:%M"))

setDT(DF)
DF[, c("d","t") := .(as.IDate(time), as.ITime(time))]
DF[, time := NULL] # remove original column

DF[ t > as.ITime("12:02"), d := d-1L ]

#    col1          d        t
# 1:    1 2015-11-09 12:01:00
# 2:    2 2015-11-09 12:02:00
# 3:    3 2015-11-08 12:03:00

这些是基于整数的,因此您无法在 t 中存储小数秒。