Вы можете sample
по unique
id, используя sapply
.
set.seed(42)
dat$visit <- unlist(lapply(unique(dat$id), function(i) sample(dat$visit[dat$id == i])))
dat
# id visit
# 1 10 2
# 2 10 1
# 3 10 3
# 4 20 3
# 5 20 1
# 6 20 2
# 7 30 3
# 8 30 1
# 9 30 2
Редактировать: Для выборки также порядок идентификаторов , вы можете сэмплировать строки впоследствии, dat[sample(nrow(dat)), ]
. Или все вместе в transform()
:
set.seed(42)
transform(dat,
visit=unlist(lapply(unique(dat$id), function(i)
sample(dat$visit[dat$id == i]))))[sample(nrow(dat)), ]
# id visit
# 8 30 3
# 7 30 2
# 4 20 1
# 1 10 1
# 5 20 2
# 2 10 3
# 9 30 1
# 3 10 2
# 6 20 3
Для выборки диапазонов идентификаторов при выборочных посещениях вы можете использовать подход by
.
set.seed(42)
do.call(rbind, by(dat, dat$id, function(x) {
transform(x, visit=sample(visit))
})[sample(seq(unique(dat$id)))])
# id visit
# 30.7 30 2
# 30.8 30 3
# 30.9 30 1
# 20.4 20 1
# 20.5 20 2
# 20.6 20 3
# 10.1 10 1
# 10.2 10 3
# 10.3 10 2
Объяснение: by
разбивает данные при "id"
s на список фреймов данных, который можно transform
редактировать, как указано выше, и после sample
вводить порядок rbind
ed в результирующий фрейм данных.
Данные:
(dat <- expand.grid(visit=1:3, id=(1:3)*10)[2:1])
# id visit
# 1 10 1
# 2 10 2
# 3 10 3
# 4 20 1
# 5 20 2
# 6 20 3
# 7 30 1
# 8 30 2
# 9 30 3