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

时间:2015-11-09 16:55:31

标签: r plot 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 $时间,我会

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"))

enter image description here

1 个答案:

答案 0 :(得分:4)

基础R 正如Roland建议的那样,这可以在

的基础上完成
# 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
)

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

# '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")的“值”部分记录了此行为: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中存储小数秒。