Скользящий список за неравное время в XTS

У меня есть биржевые данные на уровне тиков, и я хотел бы создать скользящий список всех тиков за предыдущие 10 секунд. Приведенный ниже код работает, но для больших объемов данных требуется очень много времени. Я хотел бы векторизовать этот процесс или как-то еще ускорить его, но я ничего не придумываю. Буду признателен за любые предложения или подталкивания в правильном направлении.

library(quantmod)
set.seed(150)

# Create five minutes of xts example data at .1 second intervals
mins  <- 5
ticks <- mins * 60 * 10 + 1


times <- xts(runif(seq_len(ticks),1,100), order.by=seq(as.POSIXct("1973-03-17 09:00:00"),
                                                       as.POSIXct("1973-03-17 09:05:00"), length = ticks))

# Randomly remove some ticks to create unequal intervals
times <- times[runif(seq_along(times))>.3]

# Number of seconds to look back
lookback  <- 10
dist.list <- list(rep(NA, nrow(times)))

system.time(
  for (i in 1:length(times)) {

    dist.list[[i]] <- times[paste(strptime(index(times[i])-(lookback-1), format = "%Y-%m-%d %H:%M:%S"), "/",
                                  strptime(index(times[i])-1, format = "%Y-%m-%d %H:%M:%S"), sep = "")]
  }
)
>  user  system elapsed 
   6.12    0.00    5.85 

person Bryan S    schedule 23.05.2012    source источник


Ответы (1)


Вы должны проверить функцию window, это сделает ваш подвыбор дат намного проще. Следующий код использует lapply для выполнения работы цикла for.

# Your code
system.time(
  for (i in 1:length(times)) {

    dist.list[[i]] <- times[paste(strptime(index(times[i])-(lookback-1), format = "%Y-%m-%d %H:%M:%S"), "/",
                                  strptime(index(times[i])-1, format = "%Y-%m-%d %H:%M:%S"), sep = "")]
  }
  )

#    user  system elapsed 
#    10.09    0.00   10.11

# My code 
system.time(dist.list<-lapply(index(times),
    function(x) window(times,start=x-lookback-1,end=x))
)
#    user  system elapsed 
#    3.02    0.00    3.03 

Так, примерно на треть быстрее.

Но если вы действительно хотите ускорить процесс и готовы отказаться от миллисекундной точности (что, как я думаю, неявно делает ваш исходный метод), вы можете просто запустить цикл для уникальных комбинаций даты-часа-секунды, потому что все они вернутся то же временное окно. Это должно ускорить процесс примерно в двадцать или тридцать раз:

dat.time=unique(as.POSIXct(as.character(index(times)))) # Cheesy method to drop the ms.
system.time(dist.list.2<-lapply(dat.time,function(x) window(times,start=x-lookback-1,end=x)))

# user  system elapsed 
# 0.37    0.00    0.39 
person nograpes    schedule 23.05.2012
comment
Это хороший момент, и это, безусловно, тот тип экономии времени, который я ищу. Спасибо! - person Bryan S; 23.05.2012