Как мне сгенерировать диапазон конкретных чисел с учетом среднего? - PullRequest
0 голосов
/ 09 ноября 2018

Дан вектор указанных значений, например:

x = c(4.0, 3.7, 3.3, 3.0, 2.7, 2.3, 2.0, 1.7, 1.3, 1.0)

Я хотел бы создать новый вектор любой длины, состоящий только из значений в x, выбранных случайным образом, что приведет к объединенному среднему значению 3.15. Я попытался использовать функцию rnorm(), но, тем не менее, я могу генерировать только случайные числа, которые равны среднему значению 3.15, а не указанным значениям, которые я хотел. Кто-нибудь может указать мне правильное направление?

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Вот мой метод грубой силы:

samp315<-function(n=20, desmean=3.15, distance=0.001) { # create a function with default n=20 and range 3.149-3.151
  x<- c(4.0, 3.7, 3.3, 3.0, 2.7, 2.3, 2.0, 1.7, 1.3, 1.0)
  samp<-0 # reset samp to 0
  i<-0 # reset my counter to zero
  while (!between(mean(samp),desmean-distance,desmean+distance) & i<1000000) {  # the following will run continuously until a sample (samp) with a mean that falls within the specified range is found, OR until 1 million attempts have been made
    samp<-sample(x,n,replace=TRUE) # try to generate a sample of n times from the list of values (x)
    i=i+1 # add to counter towards 1 million
   }
  ifelse(i<1000000,samp,warning("Couldn't find an appropriate sample, please select a lower n, a desired mean closer to 2.5, or a greater distance"))  # if the while loop ended because the counter reached a million, exit with an error, otherwise, return the contents of samp.
 }

Теперь, каждый раз, когда вы делаете samp315():

eg<-samp315()
mean(eg)
[1] 3.15
eg
[1] 3.0 3.7 3.0 3.7 3.3 3.7 3.3 3.3 4.0 1.0 1.7 3.0 2.0 4.0 3.7 3.7 2.3 3.3 4.0 3.3

Если вам нужен образец другой длины, просто поместите любое число внутри samp315(). Однако чем больше число, тем больше времени потребуется для поиска образца, который получит желаемое среднее значение.

Вы также можете изменить желаемое среднее значение, установив desmean, и поиграть с диапазоном, изменив distance на любое расстояние (+/-) от желаемого среднего значения. По умолчанию n = 20, в диапазоне от 3,149 до 3,151.

Чтобы избежать бесконечного цикла для маловероятных комбинаций n и диапазона, я установил максимум 1 м выборок, после чего функция завершает работу с предупреждением.

0 голосов
/ 09 ноября 2018

Как указал @mickey, мы можем взвесить вероятность каждого элемента в зависимости от того, насколько он далеко от среднего значения. Однако, это не совсем работает, потому что в х меньше элементов, чем желаемое среднее значение, что искажает выборку к ним. Мы можем объяснить это, корректируя вероятности относительно того, сколько элементов выше или ниже среднего значения желания:

x = c(4.0, 3.7, 3.3, 3.0, 2.7, 2.3, 2.0, 1.7, 1.3, 1.0)
n = 100000
xbar=3.15

xhi = x[which(x>xbar)]
xlo = x[which(x<xbar)]
probhi = 1/(xhi-xbar)
problo = 1/(xbar-xlo)

probhi = probhi * length(problo) / length(probhi)

n=1e5
set.seed(1)
y = sample(x, size = n, replace = TRUE, prob = c(probhi,problo))
mean(y)
# [1] 3.150216
0 голосов
/ 09 ноября 2018

Проблема с вашим вопросом заключается в том, что существует бесконечное количество способов отбора проб из

x = c(4.0, 3.7, 3.3, 3.0, 2.7, 2.3, 2.0, 1.7, 1.3, 1.0)

, чтобы получить среднее значение примерно 3.15, вам просто нужно указать вероятность для каждого значения.

Ведение

n = 20
sample(x, n, replace = TRUE)

предполагает, что каждое значение одинаково вероятно, и вы получите среднее значение, близкое к 2.5. Но если вы переоцениваете вероятности, вы можете приблизиться к тому, что вы хотите. Один из способов сделать это может быть

p = 1/(x - 3.15)^2    # or try p = 1/abs(x - 3.15)
sample(x, n, replace = TRUE, prob = p)

где p взвешивает значения ближе к 3.15 выше, так что они с большей вероятностью будут приняты. Он не идеален (имеется в виду, что истинное ожидаемое значение примерно равно 3.12, а большинство значений просто 2.7, 3.0 и 3.3), но, опять же, единого решения не существует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...