Найти значения диапазона, где X - средняя точка - PullRequest
2 голосов
/ 18 апреля 2011

У меня есть набор чисел от 0 до 1. Учитывая значение X в наборе, я хотел бы найти значения диапазона (высокие и низкие), где Y% значений в наборе находятся в пределах высокойи низкий, а где X - средняя точка.

Итак, скажем, числа распределены равномерно.Учитывая X = 0,4 и Y = 20%, мне нужна функция, которая даст мне:

high = 0,5 low = 0,3

Как я могу сделать это в R?

Ответы [ 2 ]

4 голосов
/ 18 апреля 2011

Обновление: В свете дополнительной информации из комментариев, это будет делать то, что хочет ОП:

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

ОП ответила на вопросы ниже, и версия функции выше делает, как было запрошено, и в свете комментариев.

ТамЕсть несколько вопросов для решения:

  • Что вы хотите сделать, если y% данных не является целым числом? На данный момент, если y% данных оценивается как 4.2 Я округляю до 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
2 голосов
/ 19 апреля 2011

Вот довольно короткая форма

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 

И иллюстрация, воспроизводящая пример Гевина Симпсона:

> set.seed(1)
> interval(data=runif(20), centre=0.4, qrange=0.2)
      30%       40%       50% 
0.3800352 0.3841037 0.5728534 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...