R 有效计算自快照日期最后一个生日起的月数(连续)
我有一个data.frame,它包含两个日期列,一个是个人的出生日期(R 有效计算自快照日期最后一个生日起的月数(连续),r,plyr,lubridate,R,Plyr,Lubridate,我有一个data.frame,它包含两个日期列,一个是个人的出生日期(DOB),另一个是时间参考点(Snapshot.date),假设这是我们最后一次看到那个人的日期。还有其他列(省略),因此我理想情况下希望将结果作为列添加到现有的data.frame中 我想计算个人的上一个生日(相对于Snapshot.Date)和Snapshot.Date之间(连续)的月数 我尝试过plyr解决方案和base sapply解决方案,它们都比我预期的慢——(我需要在我的'real'data.frame中处理一百
DOB
),另一个是时间参考点(Snapshot.date
),假设这是我们最后一次看到那个人的日期。还有其他列(省略),因此我理想情况下希望将结果作为列添加到现有的data.frame中
我想计算个人的上一个生日(相对于Snapshot.Date)和Snapshot.Date
之间(连续)的月数
我尝试过plyr解决方案和base sapply解决方案,它们都比我预期的慢——(我需要在我的'real'data.frame中处理一百万行)
首先,这里是一个测试数据集。20条原始记录(2月29日的“特殊”案例,仅存在于闰年)
还有计算月份的功能(我相信这也可以改进)
对于基数为20的记录,以下是所需的输出:
Snapshot.Date DOB Months.Since.Birthday
32806 2015-05-31 1961-06-26 11.1643836
21294 2014-03-31 1965-01-25 2.1972603
14880 2013-07-31 1939-09-27 10.1315068
21730 2014-03-31 1952-07-14 8.5589041
17525 2013-10-31 1965-04-05 6.8547945
8516 2013-02-28 1945-06-20 8.2630137
11068 2013-04-30 1954-08-15 8.4931507
11751 2013-05-31 1969-06-11 11.6575342
2564 2012-08-31 1965-10-27 10.1315068
3832 2012-09-30 1957-09-24 0.1972603
802276 2015-06-30 1987-04-21 2.2958904
1031697 2015-06-30 1970-08-03 10.8876712
129222 2015-06-30 1962-09-12 9.5917808
588224 2015-06-30 1983-12-31 5.9863014
1093247 2015-06-30 1968-12-18 6.3945205
878037 2015-06-30 1994-07-26 11.1315068
370736 2015-06-30 1992-08-11 10.6246575
709108 2015-06-30 1985-04-25 2.1643836
861908 2015-06-30 1973-08-16 10.4602740
2199 2012-08-31 1944-02-29 6.0986301
扩展数据集以进行基准测试:
# Make 5000 records total for benchmarking, didn't replicate Feb 29th
# since it is a very rare case in the data
set.seed(1)
data.test = rbind(data.test, data.test[sample(1:19, size = 4980, replace = TRUE),])
start.time = Sys.time()
res = suppressMessages(adply(data.test , 1, transform, Months.Since.Birthday = months_since_last_birthday(Snapshot.Date, DOB)))
end.time = Sys.time()
# end.time - start.time
# Time difference of 1.793945 mins
start.time = Sys.time()
data.test$Months.Since.Birthday = suppressMessages(sapply(1:5000, function(x){return(months_since_last_birthday(data.test$Snapshot.Date[x], data.test$DOB[x]))}))
end.time = Sys.time()
# end.time - start.time
# Time difference of 1.743053 mins
我做错什么了吗?你觉得这真的很慢吗?
欢迎任何反馈 除非我遗漏了一些明显的东西,否则在
R
中有许多内置的处理时间数据的方法,特别是base::difftime
,这可能会为您节省一些麻烦
获取上述数据集数据。测试:
data.test$dif <- round(as.vector(as.double(difftime(strptime(data.test$Snapshot.Date, format = "%Y-%m-%d"), strptime(data.test$DOB, format = "%Y-%m-%d"), units = "days"))) %% 365, 1)
data.test$dif谢谢,我会有闰年的特例。
# Make 5000 records total for benchmarking, didn't replicate Feb 29th
# since it is a very rare case in the data
set.seed(1)
data.test = rbind(data.test, data.test[sample(1:19, size = 4980, replace = TRUE),])
start.time = Sys.time()
res = suppressMessages(adply(data.test , 1, transform, Months.Since.Birthday = months_since_last_birthday(Snapshot.Date, DOB)))
end.time = Sys.time()
# end.time - start.time
# Time difference of 1.793945 mins
start.time = Sys.time()
data.test$Months.Since.Birthday = suppressMessages(sapply(1:5000, function(x){return(months_since_last_birthday(data.test$Snapshot.Date[x], data.test$DOB[x]))}))
end.time = Sys.time()
# end.time - start.time
# Time difference of 1.743053 mins
data.test$dif <- round(as.vector(as.double(difftime(strptime(data.test$Snapshot.Date, format = "%Y-%m-%d"), strptime(data.test$DOB, format = "%Y-%m-%d"), units = "days"))) %% 365, 1)
data.test$dif <-
round(
as.vector(
as.double(
difftime(
strptime(data.test$Snapshot.Date, format = "%Y-%m-%d"),
strptime(data.test$DOB, format = "%Y-%m-%d"), units = "days")
)
)
%% 365,
1)