Выберите случайные и уникальные элементы из вектора - PullRequest
0 голосов
/ 24 декабря 2018

Скажем, у меня есть простой вектор с повторяющимися элементами:

a <- c(1,1,1,2,2,3,3,3)

Есть ли способ случайным образом выбрать уникальный элемент из каждого из повторяющихся элементов?Т.е. одна случайная ничья, указывающая, какие элементы сохранить:

1,4,6 ## here I selected the first 1, the first 2 and the first 3

И другая:

1,5,8 ## here I selected the first 1, the second 2  and the third 3

Я мог бы сделать это с циклом для каждого повторяющегося элемента, но я уверен, что тамдолжен быть более быстрый способ сделать это?

РЕДАКТИРОВАТЬ:

В идеале решение также должно всегда выбирать определенный элемент, если он уже является уникальным элементом.Т.е. мой вектор также может быть:

b <- c(1,1,1,2,2,3,3,3,4) ## The number four is unique and should always be drawn

1 Ответ

0 голосов
/ 24 декабря 2018

Используя базу R ave, мы могли бы сделать что-то вроде

unique(ave(seq_along(a), a, FUN = function(x) if(length(x) > 1) head(sample(x), 1) else x))
#[1] 3 5 6

unique(ave(seq_along(a), a, FUN = function(x) if(length(x) > 1) head(sample(x), 1) else x))
#[1] 3 4 7

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


Использование той же логики с sapply и split

sapply(split(seq_along(a), a), function(x) if(length(x) > 1) head(sample(x), 1) else x)

И это также будет работать с tapply

tapply(seq_along(a), a, function(x) if(length(x) > 1) head(sample(x), 1) else x)

Причина, по которой нам нужно проверить length (if(length(x) > 1)), заключается в том, что с ?sample

Если x имеет длину 1, является числовым (в смысле is.числовой) и x> = 1, выборка по выборке происходит от 1: x.

Следовательно, когда в sample() есть только одно число (n), требуется sample из 1:n (а не n), поэтому нам нужно проверить его длину,

...