![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
![]()
Сообщение
#1
|
|
Группа: Пользователи Сообщений: 262 Регистрация: 1.06.2022 Из: Донецк Пользователь №: 39632 ![]() |
Как посредством R случайным образом разделить ряд чисел на две группы заданных объемов с перебором всех возможных вариантов? Просто перемешивать исходный ряд и разделять в произвольной точке оказалось плохой идеей, так как порождаются в том числе и лишние варианты, когда состав обеих групп одинаков, но последовательность внутри них разная, например в итерации i в группе А оказываются 1, 2, 3, в группе Б - 4, 5, 6, а в итерации i+1 - соответственно 2, 1, 3 и 4, 5, 6. Если мы считаем статистику, инвариантную к порядку чисел, то эти паразитические псевдовыборки никак не сказываются на выводе, но сильно жрут вычислительные ресурсы. В общем, надо чтобы в каждой итерации группа А менялась с группой Б парой чисел.
Беглый поиск готовых решений ничего не дал. Например, в широко известном пакете permute, кажется, реализованы все мыслимые планы перестановок, кроме нужного мне. Или же я просто не допер, как его на это запрограммировать. |
|
![]() |
![]() |
![]() |
![]()
Сообщение
#2
|
|
Группа: Пользователи Сообщений: 262 Регистрация: 1.06.2022 Из: Донецк Пользователь №: 39632 ![]() |
При неравных объемах выборок обнаружился баг - чувствительность к тому, что назначать х, а что у. Для правильного результата (соответствующего результатом oneway_test() из coin, требуется чтобы икс был длиннее игрека. Так и не понял в чем загвоздка но поваксил, тупо поменяв х и у местами в случае если второй длиннее. Принимайте обновленную версию функции:
Код recombmeandifftest2<-function(x, y) { if(length(y)>length(x)) { x_<-y y_<-x} else { x_<-x y_<-y } k<-length(x_) xy<-c(x_, y_) n<-length(xy) id<-1:n combmat<-combn(id, k) recmeandiff<-function(X, xy) { x<-xy[X] y<-xy[-X] meandiff<-abs(mean(x)-mean(y)) return(meandiff) } diffobs<-abs(mean(x_)-mean(y_)) diffsim<-apply(combmat[,2:ncol(combmat)], 2, recmeandiff, xy=xy) res<-as.numeric(round(diffsim, digits=6)>=round(diffobs, digits=6)) p<-(1+sum(res))/(ncol(combmat)) return(list(diffobs, p)) } Недостаток лишь один - думает медленно и жрет много памяти. Понятно, что пакет coin гораздо вычислительно эффективнее, чем моя самоделка, тем не менее не верю, что он генерирует все (n1+n2)! перестановок, скорее ограничивается все теми же уникальными сочетаниями, что и мой код. Потому как в случае с n1=15 и n2=10 на все про все у oneway_test() уходит лишь пара секунд. Для сравнения при вышеуказанных объемах выборок это 3268760 при сочетаниях и 15511210043330986055080688 при полной рандомизации. Очевидно, что второе вычислительно недостижимо, по крайней мере за те пару секунд ![]() Игорь, а в Вашем ПО количество перестановок получается какое? Сообщение отредактировал ИНО - 1.06.2025 - 17:38 |
|
![]() |
![]() |
![]() ![]() |