【发布时间】:2020-09-05 18:57:44
【问题描述】:
我有一个大型数据集,我使用 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
我最大的问题是我有一个庞大的数据集,查看多个时间段并且需要迭代每个月和库存,所以我的解决方案不可行大规模。
- 您对如何避免使用循环但获得相同结果有什么建议吗?
附:我不是高级程序员,如果我遗漏了一些细节,请见谅
用于复制的样本数据:
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"))
【问题讨论】:
-
@AaronMontgomery,这看起来很奇怪,我在编辑之前输入了我的数据。我在编辑之前重新添加了结构,现在应该可以工作了:)
-
哦,是的,这是故意的。一个预循环和一个结果,显示相同的样本,对不起
标签: r dplyr rank percentile closest