来自在线数据的日期字段操作 - sqldf

时间:2016-06-20 21:22:49

标签: r sqldf

我正在使用具有日期的在线数据集。我试图使用R(sqldf)基于日期执行操作,但它不起作用。我可以使用其他包解决我的问题,但我想通过使用SQL查询限制我的分析来解决这个问题。

我将首先使用简单示例和本地数据集展示我想要做的事情:

library(sqldf)
Name <- c('A', 'B', 'C', 'D', 'E')
DOB <- c('1989-08-19','1993-07-14', '1982-12-16', '1934-11-04', '2010-02-19')
dt1 <- data.frame(Name, DOB)
dt1
str(dt1)

使用此我可以使用sqldf计算年龄,如下所示,并获得正确的结果:

sqldf("select name, current_date, DOB from dt1")
sqldf("select name, current_date, DOB, current_date-DOB as AGE from dt1")
sqldf("select name, current_date, DOB, current_date-DOB as AGE from dt1 
  where DOB >'1990-01-01'")

我在Google云端硬盘中创建了完全相同的数据集,我正在尝试复制上述脚本。

library(gsheet)
dt2 <- gsheet2tbl("https://docs.google.com/spreadsheets/d/1E3lFgsee9FZL0NERAyDwRYvYqpjsMJ-9aLzj9rJcBc4/edit?usp=sharing")
dt2
str(dt2)
sqldf("select name, current_date, DOB from dt2")
sqldf("select name, current_date, DOB, current_date-DOB as AGE from dt2")
sqldf("select name, current_date, DOB, current_date-DOB as AGE from dt2 
  where DOB >'1990-01-01'")

它会在数千年内恢复年龄!

试图更改日期格式

dt2 <- gsheet2tbl("Same as Above")
str(dt2)
dt2
dt2$DOB <- as.Date(dt$DOB, "%y/%m/%d")
str(dt2)
dt2

由于DOB已成为NAs,我被卡住了,所以我尝试了不同的日期格式

dt2 <- gsheet2tbl("Same as Above")
str(dt2)
dt2
dt2$DOB <- as.Date(dt2$DOB, "%y-%m-%d")
str(dt2)
dt2

同样的问题,所以我试图转换为因子

dt2 <- gsheet2tbl("Same as above")
str(dt2)
dt2
dt2$DOB <- as.factor(dt2$DOB)
str(dt2)
dt2
sqldf("select name, current_date, DOB from dt2")
sqldf("select name, current_date, DOB, current_date-DOB as AGE from dt2")
sqldf("select name, current_date, DOB, current_date-DOB as AGE from dt2 
  where DOB >'1990-01-01'")

回到原点,年龄是几千年! 有关如何使用SQL查询解决此问题的任何建议将不胜感激。 感谢。

PS我下载数据并将其作为csv导入时遇到同样的问题。

1 个答案:

答案 0 :(得分:0)

如果您对字符串变量进行操作,您的算法将无法为您提供正确的AGE。以下是如何做到的:

library(gsheet)
dt2 <- gsheet2tbl("https://docs.google.com/spreadsheets/d/1E3lFgsee9FZL0NERAyDwRYvYqpjsMJ-9aLzj9rJcBc4/edit?usp=sharing")

# Convert date to a "real date"
dt2$DOB <- as.Date(dt2$DOB, "%m/%d/%Y")

# Add today's date, also as a "real date"
dt2$today <- as.Date(Sys.Date())

# Perform calculation for age
sqldf("select name, today, DOB, floor((today-DOB)/365.25) as AGE from dt2")

结果

  Name      today        DOB AGE
1    A 2016-06-20 1989-08-19  26
2    B 2016-06-20 1993-07-14  22
3    C 2016-06-20 1982-12-16  33
4    D 2016-06-20 1934-11-04  81
5    E 2016-06-20 2010-02-19   6

在OP的评论后编辑...

对于第三个查询,我们可以像使用today列一样在表格中包含截止日期,或者使用以下替代方法:

sqldf(paste0("select name, today, DOB, floor((today-DOB)/365.25) as AGE from dt2 where DOB > ", 
             as.integer(as.Date('1990-01-01'))))

第三次查询的结果

  Name      today        DOB AGE
1    B 2016-06-20 1993-07-14  22
2    E 2016-06-20 2010-02-19   6