Улучшение скорости начала цикла при сравнении значений даты и времени - PullRequest
0 голосов
/ 23 октября 2018

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

dat = structure(list(Date = structure(c(1508641200, 1508643000, 1508644800, 
1508646600, 1508648400, 1508650200, 1508652000, 1508653800, 1508655600, 
1508657400, 1508659200, 1508661000, 1508662800, 1508664600, 1508666400, 
1508668200, 1508670000, 1508671800, 1508673600, 1508675400, 1508677200, 
1508679000, 1508680800, 1508682600, 1508684400, 1508686200, 1508688000, 
1508689800, 1508691600, 1508693400), class = c("POSIXct", "POSIXt"
), tzone = "EST"), X = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), tru = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0)), .Names = c("Date", "X", "tru"), row.names = c(NA, 
30L), class = "data.frame")

и,

truth = structure(list(startdate = structure(c(1509937620, 1510705200, 
1510722240, 1512245160, 1512250560, 1512251760, 1512271140, 1512274440, 
1512984360, 1512986760, 1513002600, 1513004700, 1513752000, 1513753800, 
1513775940, 1513776840, 1514268900, 1514289000, 1514307900, 1517842620, 
1518056460, 1520031660, 1520050560, 1520075580, 1520218620), class =c("POSIXct", 
"POSIXt"), tzone = ""), enddate = structure(c(1509952320, 1510718040, 
1510737240, 1512250260, 1512269640, 1512269940, 1512290280, 1512289380, 
1513001100, 1513001400, 1513023840, 1513021440, 1513772640, 1513771440, 
1513797180, 1513796280, 1514288400, 1514307600, 1514311140, 1517857320, 
1518067560, 1520049060, 1520073240, 1520078880, 1520222820), class =c("POSIXct", 
"POSIXt"), tzone = ""), Y = c(42340.1667145732, 49765.2381579195, 
48687.3848496384, 31170.9693454847, 50435.3541955455, 49757.5112973802, 
44031.8550803252, 45912.1378875664, 47193.1529894274, 49826.4304479959, 
45840.7120690243, 42483.44259103, 52188.4048476908, 52783.8164119854, 
51769.0550080142, 49866.1301140174, 52250.5531316799, 49754.6933212176, 
45256.185763228, 47742.0544890968, 53414.0366523465, 51881.9495162963, 
48632.3656223053, 44476.3677890439, 61922.0098972212)), .Names = 
c("startdate", 
"enddate", "Y"), row.names = c(NA, 25L), class = "data.frame")

Теперь я хочу взять значения из truth$Y и ввести их в dat$tru в соответствующую дату.-временные значения, заданные как эти действия, происходят между truth$startdate и truth$enddate.

В настоящее время у меня есть следующий код для этого:

for(i in 1:length(truth$startdate)){
 for(j in 1:length(dat$Date)){
  if(dat$Date[j] >= truth$startdate[i] && dat$Date[j] <= truth$enddate[i]){
    dat$tru[j] = truth$Y[i]
  }
 }
}

Есть ли более эффективный способ сделать это, избегая цикла for внутри цикла for?Заранее спасибо!

1 Ответ

0 голосов
/ 23 октября 2018

Используя функцию between из пакета dplyr, вы можете устранить внутренний цикл:

library(dplyr)

for(i in 1:length(truth$startdate)){
  dat$tru[between(dat$Date, truth$startdate[i], truth$enddate[i])] <-truth$Y[i]
}

Это должно привести к значительному улучшению производительности.
Я уверен, что это может быть и дальшеизысканный, но это быстро и легко исправить.Я предлагаю посмотреть на пакет purrr, он может предложить некоторые дополнительные улучшения производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...