在R中分配分位数,其中分位数不唯一

在R中分配分位数,其中分位数不唯一,r,quantile,R,Quantile,设x为数值、非负数据(大部分代码>有一个或多个重复值序列,即对于某些 j ,有(序列) qx[j:n] < /代码>其中 qx[j]=qx[j+2]==…====…qx[j+n]

x
为数值、非负数据(大部分<10)和
qx
length(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-If
x[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