Ускорьте / замените цикл для миллионов данных: оцените диапазон нескольких дат - PullRequest
1 голос
/ 20 сентября 2019

Добрый вечер, ребята, у меня есть 6 миллионов данных, и у них есть четыре типа.

z=structure(list(date = structure(c(11866, 16190, 14729, 11718), class = "Date"), 
           beg1 = structure(c(12264, 12264, 13970, 12264), class = "Date"), 
           end1 = structure(c(17621, 14760, 14760, 13298), class = "Date"), 
           ID1 = c(1003587, 1000396, 1010743, 1002113), beg2 = structure(c(NA, 
                                                                           14790, 14790, 13299), class = "Date"), end2 = structure(c(NA, 
                                                                                                                                     17621, 15217, 13969), class = "Date"), ID2 = c(NA, 1024488, 
                                                                                                                                                                                    1027877, 1002824), beg3 = structure(c(NA, NA, 15218, 13970
                                                                                                                                                                                    ), class = "Date"), end3 = structure(c(NA, NA, 17621, 14760
                                                                                                                                                                                    ), class = "Date"), ID3 = c(NA, NA, 1031361, 1002113), beg4 = structure(c(NA, 
                                                                                                                                                                                                                                                              NA, NA, 14790), class = "Date"), end4 = structure(c(NA, NA, 
                                                                                                                                                                                                                                                                                                                  NA, 17621), class = "Date"), ID4 = c(NA, NA, NA, 1021290), 
           realID = c(NA, NA, NA, NA)), row.names = c(267365L, 193587L, 
                                                      5294385L, 2039421L), class = "data.frame")

, и я попытался оценить и назначить идентификатор suitalbe на основе их даты, в которой диапазоны дат (используйте цикл).

for(i in 1:nrow(z)){tryCatch({print(i)
if(between(z$date[i],z$beg1[i],z$end1[i])==T){z$realID[i]=z$ID1[i]}
if(between(z$date[i],z$beg2[i],z$end2[i])==T){z$realID[i]=z$ID2[i]}
if(between(z$date[i],z$beg3[i],z$end3[i])==T){z$realID[i]=z$ID3[i]}
if(between(z$date[i],z$beg4[i],z$end4[i])==T){z$realID[i]=z$ID4[i]}},error=function(e){})}          

Код работает.Но теперь проблема в том, что у меня слишком много данных, цикл неэффективен, может быть, цикл займет почти один день.

Кто-нибудь знает, как я могу улучшить или заменить код?Большое вам спасибо.

1 Ответ

1 голос
/ 20 сентября 2019

Поскольку R является векторизованным языком, для ускорения этого кода лучше всего работать со всем вектором, а не циклически проходить через каждый элемент.
Как простое решение - использовать серию ifelse операторов.

z$realID <- ifelse(!is.na(z$beg1) & z$date> z$beg1 & z$date< z$end1, z$ID1, z$realID)
z$realID <- ifelse(!is.na(z$beg2) & z$date> z$beg2 & z$date< z$end2, z$ID2, z$realID)
z$realID <- ifelse(!is.na(z$beg3) & z$date> z$beg3 & z$date< z$end3, z$ID3, z$realID)
z$realID <- ifelse(!is.na(z$beg4) & z$date> z$beg4 & z$date< z$end4, z$ID4, z$realID)

Когда оператор if оценивает TRUE, realID обновится, если нет, он сохранит свое предыдущее значение.

...