【问题标题】:How to calculate percentile [0,1) in R such that values lies below the percentile如何计算 R 中的百分位数 [0,1) 使得值低于百分位数
【发布时间】:2020-03-19 04:40:35
【问题描述】:

我有一个代理数据框及其相应的销售产品数量

Gent_Code   number_policies
A096        3
A0828       12
A0843       2
A0141       2
B079        7
B05         3
M012        5
P010        2
S039        3

我想计算每个值 (xi) 所在的百分位数,以使数据中 p% 的值低于 xi。 百分位数的最小值为 0,最大值非常接近 1,但不是 1。

我做了以下事情:

ag_df <- mutate(ag_df, pon_percentiles = ecdf(ag_df$pon)(ag_df$pon))

summary(ag_df$pon_percentiles )
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.4805  0.4805  0.6417  0.6356  0.7738  1.0000 

但是,我希望百分位数公式计算低于某个值,而不是低于或等于该值。

因此,向量中最小值的百分位值应为 0,最大值应为接近 1 但不完全为 1 的百分位。

Current output:
0.6666667 1.0000000 0.3333333 0.3333333 0.8888889 0.6666667 0.7777778 0.3333333 0.6666667

如果我们看到上面的输出,对于 number_policies (2) 的 min,该值为 0.3333 ,但我希望这是 0。 对于 12 的最大值,它不应该是 1,而是 0.99。

我如何在 R 中做到这一点? 我已经在 ecdf、cume_distr 等基本函数中搜索了相关参数,但找不到任何参数。 有人可以帮我解决这个问题吗?

【问题讨论】:

  • 你能显示给定数据的预期输出吗?
  • 你好@RonakShah.. 现在添加,我应该早点添加它

标签: r dplyr percentile


【解决方案1】:

您可以通过分位数函数简单地做到这一点:

quantile(df, probs = c(0, 0.24, 0.49, 0.74, 0.99))

希望对你有帮助!!!

【讨论】:

  • 你好@AnandOCF .. 谢谢。但是,我希望计算每个代理所在的百分位数。所以它将适用于每一行。 A0843 2 它将是 0 百分位数,对于 number_policies 为 2 的其他记录类似
【解决方案2】:

使用percent_rank() 函数的一种解决方案是:

pkgs <- c("tidyverse", "stringi")
invisible(lapply(pkgs, require, character.only = TRUE))


set.seed(2)
n <- 30
db <- tibble(gent_code = paste0(stri_rand_strings(n, 1, '[A-Z]'),
                                stri_rand_strings(n, 4, '[0-9]')),
                 nr_pol = sample(1L:100L, n, TRUE))

db %>%
  mutate(percentile = percent_rank(nr_pol)) %>%
  print(n = n)

给出输出:

   gent_code nr_pol percentile
   <chr>      <int>      <dbl>
 1 E0188         35     0.241 
 2 S5682         91     0.862 
 3 O6192         96     0.931 
 4 E1197         97     1.000 
 5 Y9358         39     0.345 
 6 Y0069         63     0.552 
 7 D2879         14     0.138 
 8 V6778         25     0.172 
 9 M6284         75     0.759 
10 O3420         69     0.690 
11 O2301         35     0.241 
12 G1728          3     0.0345
13 T4536         38     0.310 
14 E0418          1     0     
15 K9373         44     0.414 
16 W9335         66     0.621 
17 Z4140         58     0.448 
18 F1424         62     0.517 
19 L9825         96     0.931 
20 B8411         59     0.483 
21 R0735         41     0.379 
22 K8881         81     0.793 
23 V9502         87     0.828 
24 D9827          5     0.0690
25 J5363          8     0.103 
26 M2909         68     0.655 
27 D3658         94     0.897 
28 J1312         34     0.207 
29 Z6347         63     0.552 
30 D6342         72     0.724 

如您所见,它根据需要从 0 开始,但最高百分位数将等于 1,因为它反映了数据中最多的政策数量。

编辑: 在这种情况下强制 12 等于例如第 99 个百分位数表示数据中的数据点高于 12。它将等于 1,因为您的所有数据点都小于或等于该值。

【讨论】:

  • 你好@edsandorf.. 谢谢你的解决方案。但是,在这种情况下,由于只有一个两位数的值,因此只有 1 条记录被分配 100 个百分位或 1。在下面的向量 42、29、38、42、48、46、30、35、32、48、29 中, 29 是我拥有的较长向量的一部分,所有这些行都被分配 1 ,但是,我想要的是只有最大值被分配 1。
  • 这很奇怪。我已经编辑了我的答案以包含更多记录。如您所见,只有最高值被分配了 1。但是,如果您有多个具有相同值的条目,则应将它们分配给相同的百分位数。
【解决方案3】:

我认为这是您想要的,但我不确定,您只需按照您想要的方式设置 labelsprobs

iris2 <- iris
iris2$quartile_number <- cut(iris$Sepal.Length, 
    quantile(iris$Sepal.Length) , 
    include.lowest=T,
    labels=c(.25, .5, .75, 1))

head(iris2)

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species quartile_number
1          5.1         3.5          1.4         0.2  setosa            0.25
2          4.9         3.0          1.4         0.2  setosa            0.25
3          4.7         3.2          1.3         0.2  setosa            0.25
4          4.6         3.1          1.5         0.2  setosa            0.25
5          5.0         3.6          1.4         0.2  setosa            0.25
6          5.4         3.9          1.7         0.4  setosa             0.5

【讨论】:

    【解决方案4】:
    x <- c(3, 12, 2, 2, 7, 3, 5, 2, 3)
    

    (1) 最小值 2 是 0% 百分位数, 那么你需要从你的向量中删除最小值。 (2) 最大值 12 是 99% 的百分位数, 那么你需要添加一个比最大值更大的值,并用最大值填充你的向量,使向量长度为​​ 100。

    x1 <- c(x[x > min(x)], Inf)
    x2 <- c(x1, rep(max(x), 100 - length(x1)))
    ecdf(x2)(x)
    
    > ecdf(x2)(x)
    [1] 0.03 0.99 0.00 0.00 0.05 0.03 0.04 0.00 0.03
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-31
      • 2011-12-29
      • 2013-06-20
      • 2021-02-26
      • 2021-12-26
      • 2017-12-03
      • 1970-01-01
      • 2016-07-28
      相关资源
      最近更新 更多