2016-10-29 35 views
1

我需要使用sqldf包以过滤由日期数据。řsqldf不能识别posixct

我的表, “情节” 有场“created_at,哪一类是POSIXct

episodes<-data.frame(created_at=seq(from = as.POSIXct('2016-10-01 01:00:00',tz="GMT"), length.out = 100, by = "days")) 

> class(episodes$created_at) 
[1] "POSIXct" "POSIXt" 

我得到的第二个日期:

fechaMin=min(episodes$created_at) 

library(lubridate) 
fechaSig=fechaMin+hours(24) 

然后我用过滤数据:

sqldf("SELECT * from episodes e 
where strftime('%Y/%m/%d', e.created_at, 'unixepoch')>='$fechaSig' ") 

,但我得到的所有数据。该过滤器不工作。

我也尝试没有成功:

​​
+0

只有最近的MySQL支持'Datetime'版本这是需要保持'POSIXct' “在正确的课堂上” - 所以检查你的确。对于它的价值来说,PostgreSQL自20世纪90年代以来就有这个价值。 –

+0

@DirkEddelbuettel实际上,在R中创建一个已经在R中创建的表具有相同的问题 - 请参阅该版本。 – GabyLP

回答

1

首先注意到一个库是存储包,以便sqldf是一个包,而不是库的存储库。由于library命令的不幸名称,这通常会造成混淆。

sqldf本身不支持$替换。为了得到这个结果,你需要使用fn$sqldf,其中fn来自sqldf软件包自动加载的gsubfn软件包。它将这种替换添加到它所引用的任何函数的参数中。请参阅?fn

另请注意,SQLite数据库没有日期或日期时间类,因此sqldf只是将POSIXct的内部表示形式发送到SQLite,即一个普通数字,表示自Epoch以来相对于GMT的秒数。请注意,即使它显示相对于不同时区的日期和时间,POSIXct的内部表示始终是自Epoch 相对于GMT以来的秒数。因此episodes$created_atfechSig均被送到从r到SQLite作为秒大纪元相对于GMT因为即使他们当R从数据库接收现场发回(在这一点上不能同时显示在R.这样,它只是一个普通数字)sqldf检查字段名称是否最初是POSIXct类,如果是,它会强制返回到POSIXct的数字。启发式不处理时区,因此它存储为相对于GMT(因为所有POSIXct变量都是),并且它显示在本地时区中,这是POSIXct的默认行为。

在下面的注释中,GMT比美国东部时间早4小时,比东部时间早5小时,所以答案是正确的。

episodes <- data.frame(created_at = 
seq(from = as.POSIXct('2016-10-01 01:00:00',tz="GMT"), length.out = 100, by = "days")) 

fechaMin <- min(episodes$created_at) 

library(lubridate) 
fechaSig <- fechaMin + hours(24) # or fechaMin+as.difftime(1,units="hours") w/o lubridate 

library(sqldf) 
out <- fn$sqldf("select * from episodes where created_at >= $fechaSig") 

range(episodes$created_at) 
## [1] "2016-10-01 01:00:00 GMT" "2017-01-08 01:00:00 GMT" 
range(out$created_at) 
## [1] "2016-10-01 21:00:00 EDT" "2017-01-07 20:00:00 EST" 

如果你喜欢只在GMT工作,然后确保本地时区为GMT这样的:

Sys.setenv(TZ = "GMT") 
range(out$created_at) 
## [1] "2016-10-02 01:00:00 GMT" "2017-01-08 01:00:00 GMT"