Вменение дат для пустых ячеек для большого набора данных - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть набор данных, который выглядит следующим образом:

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,Воскресенье week из 2017-05-23 равно 2017-05-21, таким образом, week1 участника B начинается с 2017-05-21, а week2 начинается с 2017-05-28).

Моя цель состоит в том, чтобы заполнить date там, где это в настоящее время NA, чтобы результат выглядел следующим образом:

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

Код, который у меня есть в настоящее время:

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"))

Проблема этого подхода в том, что я работаю с большим набором данных (~ 8 млн наблюдений), и на его запуск уходит вечность!Я читал некоторые посты о том, что все эти преобразования даты / вычисления (например, floor_date или as.Date) - это то, что занимает так много времени, и мне было интересно, есть ли способы сделать мой код более эффективным.

Спасибо!

1 Ответ

0 голосов
/ 28 февраля 2019

Как насчет просто

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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...