R: выборка данных кластера и удаление точек данных, лежащих вне интервала 1,5*

У меня есть большой набор торговых данных с apx 15 млн. строки в следующей форме:

mydata_tsample
    Size    TradingCost
    10000   80
    2733000 79.343
    750000  78.125
    750000  77.875
    150000  83.875
    105000  86.875
    105000  87.20
    105000  87.54
    70000   87.78
    70000   87.9
    175000  87.1
    175000  87.6
    200000  2
    200000  56
    200000  87.5
    200000  80
    200000  50.2
    370000  7.25
    900000  15.42

Я хотел бы запустить две петли:

1) Кластер / сортировка всех сделок с "Размер" между, скажем, 1-100'000.

2) затем удалите те сделки в этом кластере из 1), которые лежат за пределами 1,5* межквартильного диапазона, на основе "TradinCost"

3) увеличьте размер-интервал с 1) на 100'00 и теперь выполняйте то же самое для сделок с размером 100'000-200'000. Этот цикл идет до 5'000'000.

Следующий код делает это, но проблема у меня в скорости / эффективности. Как я могу написать код для расчета образца до 20 млн. линии? С помощью следующего кода это займет несколько часов.

  for (i in 0:50){
  mydata_tsample_tempI=subset(mydata_tsample,
                                      Size >=(i)*100000 &
                                      Size  <(i+1)*100000)
  quantiles = quantile(mydata_tsample_tempI$TradingCost, probs = c(.25, .75))
  range = 1.5 * IQR(mydata_tsample_tempI$TradingCost)
  mydata_tsample_tempII = subset(mydata_tsample_tempI,
                                        mydata_tsample_tempI$TradingCost > (quantiles[1] - range) &
                                        mydata_tsample_tempI$TradingCost < (quantiles[2] + range))
    mydata_tsample_new = data.frame(rbind(mydata_tsample_new, mydata_tsample_tempII))
  }

1 ответ

Решение

Вы можете векторизовать этот процесс и немного ускорить процесс. Я рассчитываю на большую скорость, вы должны взглянуть на data.table-пакет, но, возможно, этого уже может быть достаточно:

library(dplyr)
mydata_tsample %>% 
  group_by(size_groups = cut(Size, seq(0, 5000000, 100000), right = F)) %>% 
  mutate(lower_quant_range = quantile(TradingCost, probs = .25) - 1.5 * IQR(TradingCost), 
         upper_quant_range = quantile(TradingCost, probs = .75) + 1.5 * IQR(TradingCost)) %>% 
  filter(TradingCost > lower_quant_range, TradingCost < upper_quant_range) %>% 
  arrange(Size)

# A tibble: 14 x 5
# Groups:   size_groups [4]
#      Size TradingCost size_groups   lower_quant_range upper_quant_range
#     <int>       <dbl> <fct>                     <dbl>             <dbl>
#  1  10000        80.0 [0,1e+05)                 78.0               93.8
#  2  70000        87.8 [0,1e+05)                 78.0               93.8
#  3  70000        87.9 [0,1e+05)                 78.0               93.8
#  4 105000        86.9 [1e+05,2e+05)             86.1               88.2
#  5 105000        87.2 [1e+05,2e+05)             86.1               88.2
#  6 105000        87.5 [1e+05,2e+05)             86.1               88.2
#  7 175000        87.1 [1e+05,2e+05)             86.1               88.2
#  8 175000        87.6 [1e+05,2e+05)             86.1               88.2
#  9 200000        56.0 [2e+05,3e+05)              5.50             125. 
# 10 200000        87.5 [2e+05,3e+05)              5.50             125. 
# 11 200000        80.0 [2e+05,3e+05)              5.50             125. 
# 12 200000        50.2 [2e+05,3e+05)              5.50             125. 
# 13 750000        78.1 [7e+05,8e+05)             77.8               78.2
# 14 750000        77.9 [7e+05,8e+05)             77.8               78.2
Другие вопросы по тегам