2

我有一些基本上按时间解析数据集的 SQL 查询(POSIXct 日期格式):

library(sqldf)
data_2013 <- sqldf("SELECT * FROM data WHERE strftime('%Y-%m-%d', time,
'unixepoch', 'localtime') >= '2013-01-01' AND strftime('%Y-%m-%d', time,
'unixepoch', 'localtime') <= '2013-12-31'")

data_2012 <- sqldf("SELECT * FROM data WHERE strftime('%Y-%m-%d', time,
'unixepoch', 'localtime') >= '2012-01-01' AND strftime('%Y-%m-%d', time,
'unixepoch', 'localtime') <= '2012-12-31'")

data_2011 <- sqldf("SELECT * FROM data WHERE strftime('%Y-%m-%d', time,
'unixepoch', 'localtime') >= '2011-01-01' AND strftime('%Y-%m-%d', time, 
'unixepoch', 'localtime') <= '2011-12-31'")

但是,这段代码对我来说似乎很笨拙。有没有一种巧妙的方法可以将其包装成一个函数或其他一些使它更短的方法,同时仍然吐出相同的 3 个单独的数据集?

4

2 回答 2

4

between 和 fn$使用between并通过以with开头的strptime表达式来执行字符串插值:sqldffn

Time <- "strftime('%Y-%m-%d', time, 'unixepoch', 'localtime')"
st <- '2013-01-01'
en <- '2013-12-31'
fn$sqldf("select * from data where $Time between '$st' AND '$en' ")

如果需要,这可以像其他解决方案一样容易地变成一个函数。

如果是一年,可以这样简化:

Year <- "strftime('%Y', time, 'unixepoch', 'localtime')"
yr <- '2013'    
sql <- "select * from data where $Year = '$yr' "  
fn$sqldf(sql)

我们可以像这样创建一个数据框列表:

Map(function(yr) fn$sqldf(sql), as.character(2011:2013))

R/sqldf另一种可能是先在R中添加一个字符列:

data$Year <- format(data$time, "%Y")
yr <- '2013'    
sql <- "select * from data where Year = '$yr' "
fn$sqldf(sql)

R请注意,直接在 R 中执行此操作并不难:

yr <- "2013"
subset(data, format(time, "%Y") == yr)

还将其拆分为数据框列表,每年一个:

split(data, format(data$time, "%Y"))

H2 sqldf 也可以与某些其他数据库一起使用。SQLite 的问题是它没有日期/时间类型,但是 H2 数据库直接支持日期/时间作为一种类型,因此大大简化了。如果 sqldf 看到 RH2 已加载,它将使用它而不是 SQLite:

library(RH2)
library(sqldf) 
yr <- 2013
sql <- "select * from data where year(time) = $yr"
fn$sqldf(sql)
于 2013-10-28T14:14:34.207 回答
2

有了paste0你可以实现这一点:

sqlfun <- function(startdate,stopdate){
sqldf(paste0("SELECT * FROM data WHERE strftime('%Y-%m-%d', time,
    'unixepoch', 'localtime') >= '",startdate,"' AND strftime('%Y-%m-%d', time,
    'unixepoch', 'localtime') <= '",stopdate,"'"))
}

sqlfun('2013-01-01','2013-12-31')
于 2013-10-28T14:09:03.310 回答