Используя базу 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
), поэтому нам нужно проверить его длину,