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

Operations on Date Field from online data - 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'")

它returns年龄在几千年!

已尝试更改日期格式

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

我被卡住了,因为 DOB 变成了 NA,所以我尝试了不同的日期格式

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时遇到同样的问题

如果您对字符串变量进行操作,您的算法将不会为您提供正确的 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 列中那样在 table 中包含截止日期,或者使用以下替代方法:

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