将日期插值到大型数据集的空单元格

时间:2019-02-28 18:44:15

标签: r date

我有一个如下所示的数据集:

PPID      join_date      week      date         visit
A         2017-10-01     1         NA           0
A         2017-10-01     2         2017-10-08   2
A         2017-10-01     3         2017-10-15   1
A         2017-10-01     4         NA           0
B         2017-05-23     1         2017-05-21   4
B         2017-05-23     2         2017-05-28   2
B         2017-05-23     3         NA           0

week表示join_date的一周中的星期日与date的周数之差(例如,对于参与者B,{{1}的week的星期日}}是2017-05-23;因此,参与者B的2017-05-21week1开始,而2017-05-21week2开始)。

我的目标是填写2017-05-28当前不适用的地方,以使输出如下所示:

date

我当前拥有的代码是:

PPID      join_date      week      date         visit
A         2017-10-01     1         2017-10-01   0
A         2017-10-01     2         2017-10-08   2
A         2017-10-01     3         2017-10-15   1
A         2017-10-01     4         2017-10-22   0
B         2017-05-23     1         2017-05-21   4
B         2017-05-23     2         2017-05-28   2
B         2017-05-23     3         2017-06-04   0

这种方法的问题是我正在处理大型数据集(观测值约800万),并且要花很多时间才能运行!我读了一些帖子,认为所有这些日期转换/计算(例如library(dplyr) library(lubridate) df2 <- df %>% group_by(PPID) %>% mutate(date = seq(unique(floor_date(as.Date(join_date), "weeks")), unique(floor_date(as.Date(join_date), "weeks") + 7*(max(week)-1)), by="week")) floor_date)都花了很长时间,并且想知道是否有办法使我的代码更有效。

谢谢!

1 个答案:

答案 0 :(得分:1)

简单

df2$date = floor_date(df2$join_date, 'week') + 7*(df2$week-1)
#   PPID  join_date week       date visit
# 1    A 2017-10-01    1 2017-10-01     0
# 2    A 2017-10-01    2 2017-10-08     2
# 3    A 2017-10-01    3 2017-10-15     1
# 4    A 2017-10-01    4 2017-10-22     0
# 5    B 2017-05-23    1 2017-05-21     4
# 6    B 2017-05-23    2 2017-05-28     2
# 7    B 2017-05-23    3 2017-06-04     0

尽管这会为每一行计算floor_date,但它是矢量化的,而不是循环的(就像您暗中使用by所做的那样),因此对于大多数用途来说应该足够快。如果需要提高速度,可以在is.na(df2$data)上设置子集,以仅计算需要估算的行。

数据:

df2 = structure(list(PPID = c("A", "A", "A", "A", "B", "B", "B"), join_date = structure(c(17440, 
  17440, 17440, 17440, 17309, 17309, 17309), class = "Date"), week = c(1L, 
    2L, 3L, 4L, 1L, 2L, 3L), date = structure(c(NA, 17447, 17454, 
      NA, 17307, 17314, NA), class = "Date"), visit = c(0L, 2L, 1L, 
        0L, 4L, 2L, 0L)), row.names = c(NA, -7L), class = "data.frame")