У меня есть большой набор данных, в котором я ранжирую доходность своих акций с помощью функции dplyr percent_rank () на основе даты возврата. Моя проблема в том, что я хочу создать точки разрыва на уровне процентилей и не имею точно округленных процентов.
В частности, я ищу число, которое ближе всего к каждому 10-му процентилю (.1), и вот извлечение нескольких значений из моего набора данных:
sample_data[21:27,]
# A tibble: 7 x 4
PERMNO Date Ret Pct_Rank
<dbl> <date> <dbl> <dbl>
1 10065 1969-07-31 -0.142 0.360
2 10065 1969-08-29 0.126 0.331
3 10092 2002-01-31 -0.0569 0.919
4 10092 2002-02-28 -0.134 0.907
5 10092 2002-03-28 0.218 0.893
6 10092 2002-04-30 -0.137 0.701
7 10092 2002-05-31 0.0477 0.461
Я попытался выполнить цикл for, чтобы извлечь строки с наименьшим расстоянием до децилей, а затем заменить их. Кажется, что это работает, но крайне неэффективно, когда я хочу использовать его в моем исходном наборе данных, который содержит миллионы наблюдений.
store_vec <- c()
for(i in seq(0.1, 1, 0.1)){
vec <- which.min(abs(sample_data$Pct_Rank - i))
store_vec <- c(store_vec, vec)
}
sample_data$Pct_Rank[store_vec] <- round(sample_data$Pct_Rank[store_vec], digits = 1)
- Ожидаемые результаты:
sample_data[21:27,]
# A tibble: 7 x 4
PERMNO Date Ret Pct_Rank
<dbl> <date> <dbl> <dbl>
1 10065 1969-07-31 -0.142 0.360
2 10065 1969-08-29 0.126 0.3
3 10092 2002-01-31 -0.0569 0.919
4 10092 2002-02-28 -0.134 0.9
5 10092 2002-03-28 0.218 0.893
6 10092 2002-04-30 -0.137 0.7
7 10092 2002-05-31 0.0477 0.461
Моя самая большая проблема заключается в том, что у меня большой набор данных, я просматриваю несколько периодов времени и мне нужно перебирать каждый месяц и запасы, поэтому мое решение невозможно в большом масштабе.
- Есть ли у вас какие-либо предложения, как избежать использования цикла, но получить те же результаты?
P.S. Я не продвинутый программист, так что извините, если я упустил некоторые детали
Примеры данных для репликации:
structure(list(PERMNO = c(10057, 10057, 10057, 10057, 10057,
10057, 10057, 10057, 10057, 10057, 10057, 10065, 10065, 10065,
10065, 10065, 10065, 10065, 10065, 10065, 10065, 10065, 10092,
10092, 10092, 10092, 10092, 10092, 10092, 10092, 10092, 10092,
10092), Date = structure(c(-3107, -3076, -3045, -3016, -2984,
-2954, -2925, -2892, -2864, -2834, -2803, -427, -398, -366, -335,
-307, -279, -246, -217, -185, -154, -125, 11718, 11746, 11774,
11807, 11838, 11866, 11899, 11929, 11960, 11991, 12020), class = "Date"),
Ret = c(-0.018018018018018, 0.0229357798165138, -0.031390134529148,
-0.0972222222222222, 0.0615384615384615, 0.0386473429951691,
-0.0418604651162791, 0.087378640776699, 0.0491071428571429,
-0.0297872340425532, -0.0350877192982456, 0.125827814569536,
-0.0470588235294118, -0.0123456790123457, -0.04375, -0.0261437908496732,
-0.00671140939597315, 0.0135135135135135, -0.0333333333333333,
-0.172413793103448, -0.141666666666667, 0.12621359223301,
-0.0569146280579132, -0.134462678665961, 0.218348623853211,
-0.136546184738956, 0.0476744186046512, 0.148723640399556,
-0.0338164251207729, -0.0175000000000001, 0.20763358778626,
0.139907290349768, -0.11275415896488), Pct_Rank = c(0.386976744186044,
0.641597028783667, 0.713888888888882, 0.581330868761558,
0.435185185185187, 0.468952734012974, 0.414814814814816,
0.251154201292705, 0.356682027649771, 0.707834101382496,
0.602764976958531, 0.042535446205171, 0.0611902766135791,
0.0501672240802675, 0.0499999999999999, 0.030176026823135,
0.0309106098579783, 0.625104602510468, 0.741854636591494,
0.620517097581307, 0.359700249791842, 0.331136738056014,
0.919063270336911, 0.906880922950194, 0.892695006190697,
0.700745033112567, 0.460613598673312, 0.342963268675197,
0.23797780517879, 0.22267871815941, 0.426337448559662, 0.789279869067127,
0.935483870967767)), row.names = c(NA, -33L), groups = structure(list(
date = structure(c(-3107, -3076, -3045, -3016, -2984, -2954,
-2925, -2892, -2864, -2834, -2803, -427, -398, -366, -335,
-307, -279, -246, -217, -185, -154, -125, 11718, 11746, 11774,
11807, 11838, 11866, 11899, 11929, 11960, 11991, 12020), class = "Date"),
.rows = list(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L,
12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L,
23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L)), row.names = c(NA,
-33L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))