我有一个如下所示的数据集:
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-21
从week1
开始,而2017-05-21
从week2
开始)。
我的目标是填写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
)都花了很长时间,并且想知道是否有办法使我的代码更有效。
谢谢!
答案 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")