Когда я загружаю данные из вашего CSV, каждая из 5 групп имеет идентичные значения для параметра и плотности:
df
#># A tibble: 3,500 x 3
#> hrzn parameter density
#> <int> <dbl> <dbl>
#> 1 1 0.0183 0.00914
#> 2 1 0.0185 0.00905
#> 3 1 0.0187 0.00897
#> 4 1 0.0189 0.00888
#> 5 1 0.0191 0.00880
#> 6 1 0.0193 0.00872
#> 7 1 0.0194 0.00864
#> 8 1 0.0196 0.00855
#> 9 1 0.0198 0.00847
#>10 1 0.0200 0.00839
#># ... with 3,490 more rows
sapply(1:5, function(x) all(df$parameter[df$hrzn == x] == df$parameter[df$hrzn == 1]))
# [1] TRUE TRUE TRUE TRUE TRUE
sapply(1:5, function(x) all(df$density[df$hrzn == x] == df$density[df$hrzn == 1]))
# [1] TRUE TRUE TRUE TRUE TRUE
Я не уверен, является ли это ошибкой или нет, но ясно, если Вы беспокоитесь о вычислениях, все, что вы хотите сделать во всех группах, можно сделать в 5 раз быстрее, если делать это только в одной группе.
В любом случае, чтобы получить 10-й и 90-й центили для каждой гривны вам просто нужно увидеть, какой параметр находится рядом с 0,1 и 0,9 в интегральной функции распределения. Давайте обобщим, чтобы проработать это для всех групп в случае, если есть проблема с данными или вы хотите повторить это с другими данными:
library(dplyr)
df %>%
mutate(hrzn = factor(hrzn)) %>%
group_by(hrzn) %>%
summarise(centile_10 = parameter[which(cumsum(density) > .1)[1]],
centile_90 = parameter[which(cumsum(density) > .9)[1]] )
#># A tibble: 5 x 3
#> hrzn centile_10 centile_90
#> <fct> <dbl> <dbl>
#>1 1 0.0204 0.200
#>2 2 0.0204 0.200
#>3 3 0.0204 0.200
#>4 4 0.0204 0.200
#>5 5 0.0204 0.200
Конечно, они все одинаковы по упомянутым причинам выше.
Если вас беспокоит время вычислений (хотя вышеприведенное занимает всего несколько миллисекунд), и вы не возражаете против непрозрачного кода, вы можете воспользоваться порядком cut
the cumsum
всего вашего столбца density
в диапазоне от 0 до 5 с шагом 0,1, чтобы получить все 10-ые процентили, например:
summary <- df[which((diff(as.numeric(cut(cumsum(df$density), seq(0,5,.1))) - 1) != 0)) + 1,]
summary <- summary[-(1:5)*10,]
summary$centile <- rep(1:9*10, 5)
summary
#> # A tibble: 45 x 4
#> hrzn parameter density centile
#> <int> <dbl> <dbl> <dbl>
#> 1 1 0.0204 0.00824 10
#> 2 1 0.0233 0.00729 20
#> 3 1 0.0271 0.00634 30
#> 4 1 0.0321 0.00542 40
#> 5 1 0.0392 0.00453 50
#> 6 1 0.0498 0.00366 60
#> 7 1 0.0679 0.00281 70
#> 8 1 0.103 0.00199 80
#> 9 1 0.200 0.00114 90
#> 10 2 0.0204 0.00824 10
#> # ... with 35 more rows
Возможно, я вас неправильно понял, и вы на самом деле работаете в пространство параметров и хотите знать значения параметров в 10-м и 90-м центилях 5-й плотности. В этом случае вы можете воспользоваться тем фактом, что все группы одинаковы для вычисления 10-го и 90-го центилей для 5-й плотности, просто взяв 5-й root из этих двух центилей:
df %>%
mutate(hrzn = factor(hrzn)) %>%
group_by(hrzn) %>%
summarise(centile_10 = parameter[which(cumsum(density) > .1^.2)[1]],
centile_90 = parameter[which(cumsum(density) > .9^.2)[1]] )
#> # A tibble: 5 x 3
#> hrzn centile_10 centile_90
#> <fct> <dbl> <dbl>
#> 1 1 0.0545 0.664
#> 2 2 0.0545 0.664
#> 3 3 0.0545 0.664
#> 4 4 0.0545 0.664
#> 5 5 0.0545 0.664