Мне нужно запустить цикл над кадром данных с ~ 150К строк.Однако цикл должен проверять каждую строку и проверять условие, которое проверяет все остальные строки в наборе данных.Мой код отлично работает для игрушечного набора данных, он выдает правильное значение, но он слишком медленный для моего фактического набора данных.Я дал ему поработать несколько часов, а он так и не закончился.так что я надеюсь, что у кого-то есть лучшая идея, как подойти к этому.
#R version 3.5.1 Windows 64-bit
#Example dataset
my_df <- data.frame("PERSON" = c("A","A","A","B","A","A","B"),
"DATE_START" = c("2019-01-15","2019-01-10","2019-01-20","2019-01-19","2018-12-20","2018-03-03","2019-05-01"),
"DATE_FINISH" = c("2019-01-30","2019-01-18","2019-02-05","2019-01-23","2019-02-10","2018-04-01","2019-06-06")
)
#Each row is a task that the assigned person is working on
my_df
PERSON DATE_START DATE_FINISH
1 A 2019-01-15 2019-01-30
2 A 2019-01-10 2019-01-18
3 A 2019-01-20 2019-02-05
4 B 2019-01-19 2019-01-23
5 A 2018-12-20 2019-02-10
6 A 2018-03-03 2018-04-01
7 B 2019-05-01 2019-06-06
Что я хочу знать, это ДЛЯ строки 1, сколько других задач у человека А перекрывается между датами его начала и окончания?(включая строку с включенным)
Итак, я ищу ответ
PERSON DATE_START DATE_FINISH NUMBER_OF_TASKS
1 A 2019-01-15 2019-01-30 4
2 A 2019-01-10 2019-01-18 3
3 A 2019-01-20 2019-02-05 3
4 B 2019-01-19 2019-01-23 1
5 A 2018-12-20 2019-02-10 4
6 A 2018-03-03 2018-04-01 1
7 B 2019-05-01 2019-06-06 1
Так что это в основном говорит о строке 1, у человека А было 4 открытых задания
Я попытался создать элемент списка для каждой строки, которая включает диапазон дат в виде числовых значений, а затем, чтобы проверить, есть ли перекрытие, я использовал оператор% in% для сравнения не перечисленных диапазонов
Я сделал нечто подобное, используяфункция lapply (здесь не показана), но та же проблема, для выполнения которой требуется вечность.
##This is what I currently have
temp_list <- list()
num_open_tasks <- c()
open_work_cc <- c()
##Create a list of length = nrow(my_df)
##Each element in the list is a range of dates coerced to numeric
for(i in 1:nrow(my_df)){
temp_list[[i]] <- as.numeric(my_df$DATE_START[i]) :
as.numeric(my_df$DATE_FINISH[i])
}
for(i in 1:nrow(my_df)){
for(j in 1:nrow(my_df)){
##If elements from the temp_list overlap by 5 days, the overlap = 5
##I'm just checking if the overlap is greater than 0 (is there any overlap at all)
##And if the tasks belongs to the same person or not
open_work_cc[j] <- ifelse(sum(unlist(temp_list[[i]]) %in%
unlist(temp_list[[j]])) > 0 &
my_df$PERSON[i] == my_df$PERSON[j]
,1,0
)
open_work_cc_total <- sum(open_work_cc)
}
num_open_tasks[i] <- open_work_cc_total
}
my_df <- cbind(my_df, num_open_tasks)
Этот метод возвращает желаемый столбец, заполненный правильными значениями.Но я предполагаю, что есть более элегантный и значительно более быстрый метод, использующий некоторую форму разделения / применения / объединения.Любая помощь приветствуется