在R中分配分位数,其中分位数不唯一
设在R中分配分位数,其中分位数不唯一,r,quantile,R,Quantile,设x为数值、非负数据(大部分代码>有一个或多个重复值序列,即对于某些 j ,有(序列) qx[j:n] < /代码>其中 qx[j]=qx[j+2]==…====…qx[j+n]
x
为数值、非负数据(大部分<10)和qxlength(x)*(3/4)
的向量。
我需要一个索引向量qx
,称之为q_I
,其中x[I]
位于分位数qx[q_I[I]
如标题所示,问题在于qx
中可能存在非唯一值,例如,如果x
为零膨胀,则可能存在多个0值分位数,并且可能存在其他重复值。我想通过(a)循环这些等效分位数的索引序列,或(b)随机分配等效分位数的索引来处理这些情况。我想我更倾向于选择(a),但解决这两个问题都是有用的
下面是一个编辑,用于为特定的x[i]
提供确定q\u i[i]
的规则:
考虑< <代码> qx>代码>有一个或多个重复值序列,即对于某些<代码> j <代码>,有(序列)<代码> qx[j:n] < /代码>其中<代码> qx[j]=qx[j+2]==…====…qx[j+n]
。设k=c(j,j+1,…,j+n)
。然后q_i[i]好的,我有一些代码从您的代码继续到场景a(回收)下的最终q_i。我希望它能漂亮一点,但希望它能有所帮助
注意:
-这假设length(x)
length(qx)
length(x)/2
-在下面的代码解释中,q_i
指的是问题末尾的值,在进行任何值的回收或替换之前
## Start off with the code provided in the question...
# 1. For each distinct q_i, calculate the number of occurrances, and how far we can recycle it
df <- data.frame(lower=sort(unique(q_i)), freq=as.integer(table(q_i)))
df$upper <- c(df$lower[-1] - df$lower[-nrow(df)], 1) + df$lower - 1
df$upper <- df$upper - as.numeric(df$upper > df$lower & qx[df$upper] < qx[df$upper + 1])
# 2. Identify when there's a (single) number we can't recycle, and identify which position it's in
# e.g. is it the third time q_i == 10?
df$special_case <- rep(NA, nrow(df))
df$special_case[df$lower < df$upper] <- sapply(df$lower[df$lower < df$upper], function(low) {
bin <- x[q_i==low]
if(length(unique(bin)) > 1) {
return(match(min(bin), bin))}
else return(NA)})
# 3. For each row of df, get a vector of (possibly recycled) numbers
recycled <- apply(df, 1, function(x) {
out <- rep(x["lower"]:x["upper"], length.out=x["freq"])
# This part modifies the vector created to handle the 'special case'
if(!is.na(x["special_case"])) {
out[x["special_case"]] <- x["lower"]
if(x["special_case"] < x["freq"]) {
out[(x["special_case"]+1):x["freq"]] <- out[x["special_case"]:(x["freq"]-1)]
}
}
return(out)
})
# 3b. Make this follow the same order as q_i
q_i_final <- unlist(recycled)[order(order(q_i))]
q_i_final
[1] 10 1 19 11 5 19 13 10 17 16 17 6 2 15 3 9 11 7 1 16 2 3 5 13 6
<>这个代码是基于@ HoGeNoovice的回答,但不考虑特殊情况。
它还有一个附加条件,可以正确地循环第一个重复分位数序列的值。这是我在问题中的一个错误,我最初从我想要的答案中省略了4
的q_I
,但它应该是.bincode()
为1
的q_I
分配的数据值回收的索引之一
df我不确定我是否完全理解问题所在。如果bincode不能满足您的需要,那么您可以编写自己的函数来实现它吗?关于如何从x和qx到q_i,你有什么逻辑吗?我搞不懂你在干什么doing@kmeanskeal,您的解决方案中没有8、12、14或18是因为“在上述场景(a)下”,还是应该包括它们(例如,序列中的第二个17应该是18)?@RAB据我所知,qx只是x的一些分位数。q_i表示x[j]介于qx[q_i[j]]和qx[q_i[j]+1]之间。@RAB,我想写我自己的函数。我发表这篇文章是为了防止有人知道如何有效地实现bincode或相关函数来实现我的目标。我不确定我能比我现在更好地概括出从x和qx到qu I的“逻辑”——很抱歉,你不能理解我在做什么。我将数据分组到分位数中,其中有重复的分位数,并且需要一种方法将数据点“分布”到重复的分位数上。@hodgenovice,是的-这些值不存在的原因是没有数据落入这些索引中分位数所描绘的“箱”中。例如,对于值8,数据点必须大于3.5,感谢您的回复!你的方法很有道理,非常有用。不过,我对这个特例感到困惑。为什么您认为在这些情况下循环使用qx
索引是不合适的?e、 例如,假设您将我的问题中的x[5]
替换为3.499
。如果k=5和j=11,我们会有这个特殊情况,对吗?x[5]
和x[11]
都属于相同的重复分位数(也就是说,它们可以正确地分配到qx[5:7]
中的任何一个),在更改q_i[c(5,11)
@kmeanskeal-Ifx[5]时,您应该像往常一样回收这些qx
索引
是3.499
,那么据我所知,它只能分配给qx[5]
,因为qx[5]
x[5]
qx[6]
不在qx[6]
和qx[7]
之间。而且,如果你只调整x[5],情况就不太像我说的那样了
然后q_i
(回收前)为x[5]给出不同的值
和x
=3.5的值,因此您可以简单地回收x
=3.5的值,并保留3.499大小写不可回收。我编辑了这个问题,试图解释我对类似示例的意思。哎哟,您说得很对,因为我看到的是四舍五入的qx
值!非常感谢为更新您的答案,以提供该特殊情况的一个很好的示例。很抱歉,在这里花了这么长时间作出响应。我现在理解了这个问题,但我没有想到这个特殊情况以及如何处理它。但是,我想将这些数据视为等效数据进行分类,因为,例如,如果没有重复的分位数但是我们有相同的分位数值,那些特殊情况(x[12]
,在您的编辑中)和较大的值(x[5]
)将被正确地分配到相同的分位数。我编辑了这个问题以提及这个特殊情况。我添加了对您的代码的修改,作为答案。
# Code copied from question, changes as follows:
# x[12] changed from 3.5 to 3.4
# x[13] and x[21] changed from 0.0 to 10.0
x <- c(5.8, 0.0, 16.1, 5.8, 3.5, 13.8, 6.9, 5.8, 11.5, 9.2, 11.5,
3.4, 10.0, 8.1, 0.0, 4.6, 5.8, 3.5, 0.0, 10.3, 10.0, 0.0,
3.5, 6.9, 3.5)
pq <- seq(0, 1, length.out = 20)
qx <- quantile(x, pq)
q_i <- .bincode(x, qx, include.lowest = T, right=T)
q_i
[1] 8 1 19 8 4 19 12 8 17 14 17 4 15 13 1 8 8 4 1 16 15 1 4 12 4