我正在使用具有日期的在线数据集。我试图使用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导入时遇到同样的问题。
答案 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