sqldf 和 POSIXct

sqldf and POSIXct

sqldf 和 & POSIXct 有问题。将不胜感激

Sys.setenv(TZ = "America/Los_Angeles")
user <- read.csv("user_ori.csv",stringsAsFactors=FALSE)
user$created_on <- as.POSIXct(user$created_on,format="%Y-%m-%d %H:%M:%S",tz="America/Los_Angeles")

head(user$created_on)
[1] "2017-02-15 19:39:10 PST" "2016-05-11 22:44:58 PDT"
[3] "2017-02-06 19:25:48 PST" "2016-09-22 22:25:50 PDT"
[5] "2016-07-11 10:36:58 PDT" "2015-02-23 20:42:12 PST"

不确定为什么我混合使用 PST 和 PDT,但继续...

user.mindate <- sqldf("select min(u.created_on) as min_date
                from user u")
> user.mindate
    min_date
1 1380749081

> as.Date(user.mindate$min_date,tz="America/Los_Angeles")
[1] "3782332-08-02"

关于如何将 min_date 转换回 Date 有什么建议吗?

谢谢, 约翰

SQLite 将类似日期时间的对象存储为数字,通常 epoch seconds。这是不可避免的。

如果你阅读?as.POSIXct,你会看到

## S3 method for class 'numeric'
as.POSIXlt(x, tz = "", origin, ...)

以后

origin: a date-time object, or something which can be coerced by as.POSIXct(tz = "GMT") to such an object.

as.POSIXct(1380749081, origin="1970-01-01")
# [1] "2013-10-02 14:24:41 PDT"

问题是 SQLite 没有日期时间类型。 R 将 POSIXct 对象存储为自 1970-01-01(大纪元)以来的秒数,当这样的对象被发送到 SQLite 时,因为没有相应的类型,它只是作为原始秒数发送,即一个数字。处理后发送回 R 时,它仍然只是一个数字。

有几种方法可以解决这个问题:

1) 列名 将要成为 POSIXct 的输出列名与原来的名称相同。 sqldf 有一个启发式方法,它会查看输入和输出列名称,如果其中任何一个匹配,则假定输出应转换为与该名称的输入列相同的 class .

sqldf("select min(u.created_on) as created_on from user u")
##            created_on
## 1 2017-02-15 19:39:10

2) 方法参数 使用 method 参数明确告诉 sqldf 要分配什么 class:

sqldf("select min(u.created_on) as min_date__POISXt from user u", method = "POSIXct")
##              min_date
## 1 2017-02-15 19:39:10

3) H2 不要使用默认的 SQLite 后端,而是使用 H2 后端。 H2 确实 支持日期时间classes 所以它按预期工作。如果您为 H2 加载 RH2 驱动程序包,则 sqldf 将注意到它并使用该数据库而不是 SQLite。 ("sqldf.driver" 选项和 sqldfdrv= 参数也可用于指定后端——参见 ?sqldf 和 sqldf github 主页上的信息页。)

library(RH2)

sqldf("select min(u.created_on) as min_date from user u")
##              min_date
## 1 2017-02-15 19:39:10