【问题标题】:sqldf and POSIXctsqldf 和 POSIXct
【发布时间】:2017-11-11 10:07:06
【问题描述】:

在使用 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 有什么建议吗?

谢谢, 约翰

【问题讨论】:

  • PDTPST 的混合可能是由于夏令时(明天早上发生,不少于)。

标签: r posixct sqldf


【解决方案1】:

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

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

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

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

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

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 确实 支持日期时间类,因此它可以按预期工作。如果您为 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

【讨论】:

    【解决方案2】:

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

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

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

    以后

    origin:一个日期时间对象,或者可以被 as.POSIXct(tz = "GMT") 强制转换为这样一个对象的东西。

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

    【讨论】:

    • G. Grothendieck 的回答建议澄清:SQLite 是sqldf 的默认后端,但不是唯一的。如果只是对症状进行事后修复,我的回答的第二部分仍然是中肯的。
    猜你喜欢
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 2013-01-26
    • 2014-09-19
    • 2020-08-15
    • 2012-05-01
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多