查找范围值,其中X是中点

时间:2011-04-18 16:00:09

标签: r

我有一组从0到1的数字。给定集合中的值X,我想找到范围值(高和低),其中集合中Y%的值在高位低,X是中点。

所以让我们说数字是均匀分布的。给定X = 0.4和Y = 20%,我需要一个能给我的函数:

高= 0.5 低= 0.3

我怎么能在R?中做到这一点?

2 个答案:

答案 0 :(得分:4)

更新:根据评论中的额外信息,这将符合OP的要求:

foobar <- function(x, mid, y) {
    ## x, input data on range 0,1
    ## mid, midpoint X in OP's Q
    ## y, % of points around mid
    sx <- sort(x)
    want <- sx >= mid
    ## what do you want to do if y% of x is not integer?
    num <- floor(((y/100) * length(x)) / 2)
    high <- if((len <- length(want[want])) == 0) {
        1
    } else {
        if(len < num) {
            tail(sx, 1)
        } else {
            sx[want][num]
        }
    }
    low <- if((len <- length(want[!want])) == 0) {
        0
    } else {
        if(len < num) {
            head(sx, 1)
        } else {
            rev(sx[!want])[num]
        }
    }
    res <- c(low, high)
    names(res) <- c("low","high")
    res
}

在区间0,1上的随机值样本中给出以下内容:

> set.seed(1)
> x <- runif(20)
> sort(x)
 [1] 0.06178627 0.17655675 0.20168193 0.20597457 0.26550866 0.37212390
 [7] 0.38003518 0.38410372 0.49769924 0.57285336 0.62911404 0.66079779
[13] 0.68702285 0.71761851 0.76984142 0.77744522 0.89838968 0.90820779
[19] 0.94467527 0.99190609
> foobar(x, 0.4, 20)
      low      high 
0.3800352 0.5728534

OP回答了下面的问题,上面的函数版本按照要求并根据评论进行了。

有几个问题要处理:

  • 如果y%的数据不是整数,您想做什么?目前,如果y%的数据评估为4.2 1}}我向下舍入到floor(4.2),但我们可以向ceiling(4.2)舍入。
  • 如果在所选中点之上或之下有0个值,您想要做什么?在这些情况下,代码返回指定的极值(0,1)。
  • 如果某些值高于/低于中点但在给定方向上不足以在任何一个方向上包含y/2%,您想做什么?目前我返回位于中点上方/下方的数据的极值点。这与前一点有点不一致,我们是否应该在这种情况下返回极值0,1?

原文:这会给你你想要的,假设你陈述的假设(均匀分布在0,1范围内)

foo <- function(x, y) {
    ## x is the mid-point
    ## y is the % range about x, i.e. y/2 either side of x
    x + (c(-1,1) * (((y/100) / 2) * 1))
}

> foo(0.4, 20)
[1] 0.3 0.5

我们可以扩展函数以允许任意范围,默认值为0,1:

bar <- function(x, y, min = 0, max = 1) {
    ## x is the mid-point
    ## y is the % range about x, i.e. y/2 either side of x
    ## min, max, the lower and upper bounds on the data
    stopifnot(x >= min & x <= max)
    x + (c(-1,1) * (((y/100) / 2) * (max - min)))
}

> bar(0.4, 20)
[1] 0.3 0.5
> bar(0.6, 20, 0.5, 1)
[1] 0.55 0.65
> bar(0.4, 20, 0.5, 1)
Error: x >= min & x <= max is not TRUE

答案 1 :(得分:2)

这是一个相当简洁的表格

interval <- function(data, centre, qrange, type=1) {  #type as in ?quantile
    qcentre <- ( length(data[data<centre]) +          #quantile of centre
                 length(data[data == centre])/2 ) / length(data)
    quantile(data, c( max(0, qcentre-qrange/2), qcentre, 
                      min(1, qcentre+qrange/2) ), type=type )  
   } 

显示指定中心或最接近指定中心点的分位数,低分位数和高分位数及其值的图示:

> set.seed(42)
> interval(data=runif(1000000), centre=0.4, qrange=0.2)
 29.9793%  39.9793%  49.9793% 
0.3003162 0.3999986 0.5001484 

可以处理极端和非均匀分布的说明;请注意sqrt(0.95) = 0.974679...

> set.seed(123)
> interval(data=runif(100000)^2, centre=0.95, qrange=0.2)
  87.456%   97.456%      100% 
0.7634248 0.9499948 0.9999846 

再现了Gavin Simpson的例子:

> set.seed(1)
> interval(data=runif(20), centre=0.4, qrange=0.2)
      30%       40%       50% 
0.3800352 0.3841037 0.5728534