В кластеризованном наборе данных я хочу случайным образом выбрать несколько кластеров, а затем добавить несколько смоделированных наблюдений к выбранным кластерам. Затем я хочу создать набор данных, который объединяет смоделированные и исходные наблюдения из выбранных кластеров со всеми исходными наблюдениями из невыделенных кластеров. Я также хотел бы повторить этот процесс много раз и таким образом создать много (возможно, 1000) новых наборов данных. Мне удалось сделать это с помощью цикла for
, но я хотел бы знать, есть ли более эффективный и краткий способ сделать это. Вот пример набора данных:
## simulate some data
y <- rnorm(20)
x <- rnorm(20)
z <- rep(1:5, 4)
w <- rep(1:4, each=5)
dd <- data.frame(id=z, cluster=w, x=x, y=y)
# id cluster x y
# 1 1 1 0.30003855 0.65325768
# 2 2 1 -1.00563626 -0.12270866
# 3 3 1 0.01925927 -0.41367651
# 4 4 1 -1.07742065 -2.64314895
# 5 5 1 0.71270333 -0.09294102
# 6 1 2 1.08477509 0.43028470
# 7 2 2 -2.22498770 0.53539884
# 8 3 2 1.23569346 -0.55527835
# 9 4 2 -1.24104450 1.77950291
# 10 5 2 0.45476927 0.28642442
# 11 1 3 0.65990264 0.12631586
# 12 2 3 -0.19988983 1.27226678
# 13 3 3 -0.64511396 -0.71846622
# 14 4 3 0.16532102 -0.45033862
# 15 5 3 0.43881870 2.39745248
# 16 1 4 0.88330282 0.01112919
# 17 2 4 -2.05233698 1.63356842
# 18 3 4 -1.63637927 -1.43850664
# 19 4 4 1.43040234 -0.19051680
# 20 5 4 1.04662885 0.37842390
cl <- split(dd, dd$cluster) ## split the data based on clusters
k <- length(dd$id)
l <- length(cl)
`%notin%` <- Negate(`%in%`) ## define "not in" to exclude unselected clusters so
## as to retain their original observations
Затем создается clsamp
функция в следующем коде, которая включает два цикла for
. Первый цикл for
предназначен для исключения невыделенных кластеров, а второй цикл for
предназначен для моделирования новых наблюдений и добавления их к выбранным кластерам. Обратите внимание, что я произвольно выбираю 2 кластера (10% от общего количества наблюдений) без замены
clsamp <- function(cl, k) {
a <- sample(cl, size=0.1*k, replace=FALSE)
jud <- (names(cl) %notin% names(a))
need <- names(cl)[jud]
T3 <- NULL
for (k in need) {
T3 <- rbind(T3, cl[[k]])
}
subt <- NULL
s <- a
for (j in 1:2) {
y <- rnorm(2)
x <- rnorm(2)
d <- cbind(id=nrow(a[[j]]) + c(1:length(x)),
cluster=unique(a[[j]]$cluster), x, y)
s[[j]] <- rbind(a[[j]], d)
subt <- rbind(subt, s[[j]])
}
T <- rbind(T3, subt)
return(T)
}
Наконец, это создает список из 5 наборов данных, каждый из которых объединяет смоделированные и исходные наблюдения из выбранных кластеров со всеми исходными наблюдениями из невыделенных кластеров.
Q <- vector(mode="list", length=5)
for (i in 1:length(Q)) {
Q[[i]] <- clsamp(cl, 20)
}
Кто-нибудь знает более короткий способ сделать это? Может воспользоваться функцией replicate
? Спасибо.
clsamp
? Я просто получаю один набор данных 24x4. - person jay.sf   schedule 17.12.2020for
, спасибо! Пожалуйста, посмотрите мое решение ниже и скажите, что вы думаете. - person jay.sf   schedule 17.12.2020