我想在R中生成一个分布,给出以下score and percentile ranks。
x <- 1:10
PercRank <- c(1, 7, 12, 23, 41, 62, 73, 80, 92, 99)
例如, PercRank = 1
表示1%的数据具有value/score <= 1
(x的第一个值)。同样,PercRank = 7
表示7%的数据有value/score <= 2
等等。
我不知道如何找到基础分布。如果我能从如此多的信息中获得关于如何获得基础分布pdf
的指导,我会很高兴。
答案 0 :(得分:8)
来自Wikipedia:
分数的百分位数是其频率分布中与其相同或更低的分数百分比。
为了说明这一点,让我们创建一个分发,例如normal distribution
,mean=2
和sd=2
,以便我们以后可以测试(我们的代码)。
# 1000 samples from normal(2,2)
x1 <- rnorm(1000, mean=2, sd=2)
现在,让我们采取你在帖子中提到的percentile rank
。我们将它除以100,以便它们代表累积概率。
cum.p <- c(1, 7, 12, 23, 41, 62, 73, 80, 92, 99)/100
与这些百分位数相对应的值(scores
)是什么?
# generating values similar to your x.
x <- c(t(quantile(x1, cum.p)))
> x
[1] -2.1870396 -1.4707273 -1.1535935 -0.8265444 -0.2888791
0.2781699 0.5893503 0.8396868 1.4222489 2.1519328
这意味着1%的数据小于-2.18。 7%的数据小于-1.47等...现在,我们有x
和cum.p
(相当于您的PercRank
)。让我们忘记x1
以及这应该是正态分布的事实。为了找出它可能是什么分布,让我们通过使用获得第n和第(n-1)个元素之间差异的diff
从累积概率中获得实际概率。
prob <- c( cum.p[1], diff(cum.p), .01)
> prob
# [1] 0.01 0.06 0.05 0.11 0.18 0.21 0.11 0.07 0.12 0.07 0.01
现在,我们所要做的就是为x (x[1]:x[2], x[2]:x[3] ...)
的每个区间生成大小的样本,比如说100(可以是任意数字),然后最终从这个庞大的数据中采样多个根据需要(例如,10000)指出上述概率。
这可以通过以下方式完成:
freq <- 10000 # final output size that we want
# Extreme values beyond x (to sample)
init <- -(abs(min(x)) + 5)
fin <- abs(max(x)) + 5
ival <- c(init, x, fin) # generate the sequence to take pairs from
len <- 100 # sequence of each pair
s <- sapply(2:length(ival), function(i) {
seq(ival[i-1], ival[i], length.out=len)
})
# sample from s, total of 10000 values with probabilities calculated above
out <- sample(s, freq, prob=rep(prob, each=len), replace = T)
现在,我们有来自分发的10000个样本。我们来看看它是怎么回事。它应该类似于正态分布,均值= 2且sd = 2.
> hist(out)
> c(mean(out), sd(out))
# [1] 1.954834 2.170683
这是mean = 1.95
和sd = 2.17 (~ 2)
的正态分布(来自直方图)。
注意:我所解释的一些事情可能是环形交叉和/或代码“可能/可能不会”与其他一些发行版一起使用。这篇文章的重点只是用一个简单的例子来解释这个概念。
修改:为了澄清@Dwin's
点,我尝试了与OP问题相对应的x = 1:10
相同的代码,使用相同的代码替换x的值
cum.p <- c(1, 7, 12, 23, 41, 62, 73, 80, 92, 99)/100
prob <- c( cum.p[1], diff(cum.p), .01)
x <- 1:10
freq <- 10000 # final output size that we want
# Extreme values beyond x (to sample)
init <- -(abs(min(x)) + 1)
fin <- abs(max(x)) + 1
ival <- c(init, x, fin) # generate the sequence to take pairs from
len <- 100 # sequence of each pair
s <- sapply(2:length(ival), function(i) {
seq(ival[i-1], ival[i], length.out=len)
})
# sample from s, total of 10000 values with probabilities calculated above
out <- sample(s, freq, prob=rep(prob, each=len), replace = T)
> quantile(out, cum.p) # ~ => x = 1:10
# 1% 7% 12% 23% 41% 62% 73% 80% 92% 99%
# 0.878 1.989 2.989 4.020 5.010 6.030 7.030 8.020 9.050 10.010
> hist(out)
答案 1 :(得分:1)
我认为您需要ecdf
函数,该函数在quantile
帮助页面上被提及为?quantile
函数的反函数。
# construct your vector containing the data
PercRank <- c(1, 7, 12, 23, 41, 62, 73, 80, 92, 99)
# construct an empirical cumulative distribution function
# which is really just the `inverse` of `quantile
Fn <- ( ecdf( PercRank ) )
# note that the `ecdf` function returns a function itself.
# calculate what percent of `PercRank` is below these integers..
Fn( 0 )
Fn( 1 )
Fn( 2 )
Fn( 3 )
Fn( 6 )
Fn( 7 )
Fn( 8 )
# re-construct your `x` vector using PercRank
Fn( PercRank ) * 10
答案 2 :(得分:-1)
此给定生成的数据集具有您指定的功能。如果你想要更多“随机性”,你可以在百分比范围内减去一些随机数到rep
结果在匿名函数内:
> mapply( function(x,y) rep(x, each=y), (x), diff(c(PercRank, 100) ) )
[[1]]
[1] 1 1 1 1 1 1
[[2]]
[1] 2 2 2 2 2
[[3]]
[1] 3 3 3 3 3 3 3 3 3 3 3
[[4]]
[1] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
[[5]]
[1] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
[[6]]
[1] 6 6 6 6 6 6 6 6 6 6 6
[[7]]
[1] 7 7 7 7 7 7 7
[[8]]
[1] 8 8 8 8 8 8 8 8 8 8 8 8
[[9]]
[1] 9 9 9 9 9 9 9
[[10]]
[1] 10