Я думаю, это то, что вы ищете. Давайте начнем с ваших данных в воспроизводимом формате:
data1 <- structure(list(id = structure(1:14, .Label = c("1001", "1002",
"1003", "3002", "3003", "3005", "3006", "3007", "4001", "4002",
"5006", "5007", "5009", "5010"), class = "factor"), group = structure(c(1L,
1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 4L, 4L), .Label = c("1",
"2", "3", "4"), class = "factor"), y = structure(c(1L, 4L, 8L,
7L, 4L, 10L, 9L, 2L, 3L, 4L, 11L, 12L, 6L, 5L), .Label = c("10",
"11", "12", "15", "19", "22", "24", "3", "32", "37", "7", "9"
), class = "factor")), class = "data.frame", row.names = c(NA,
-14L))
И просто чтобы убедиться:
data1
#> id group y
#> 1 1001 1 10
#> 2 1002 1 15
#> 3 1003 1 3
#> 4 3002 2 24
#> 5 3003 2 15
#> 6 3005 2 37
#> 7 3006 2 32
#> 8 3007 2 11
#> 9 4001 3 12
#> 10 4002 3 15
#> 11 5006 4 7
#> 12 5007 4 9
#> 13 5009 4 22
#> 14 5010 4 19
Мы начнем с разделения фрейма данных на group
на меньшие фреймы данных, используя функцию split
. Это дает нам список с четырьмя фреймами данных, каждый из которых содержит всех членов своей соответствующей группы. (set.seed
предназначен только для того, чтобы сделать этот пример воспроизводимым).
set.seed(69)
split_dfs <- split(data1, data1$group)
Теперь мы можем сэмплировать этот список, дав нам новый список из четырех фреймов данных, составленных с заменой из split_dfs
. Каждый из них снова будет содержать всех членов своей соответствующей группы, хотя, конечно, некоторые целые группы могут быть взяты несколько раз, а другие целые группы вообще не отобраны.
sampled_group_dfs <- split_dfs[sample(length(split_dfs), replace = TRUE)]
Теперь мы можем сделать выборку в пределах каждой группы путем выборки с заменой из строк каждого фрейма данных в нашем новом списке. Мы делаем это для всех наших фреймов данных в нашем списке, используя lapply
all_sampled <- lapply(sampled_group_dfs, function(x) x[sample(nrow(x), replace = TRUE), ])
Все, что остается, это соединить все результирующие фреймы данных в этом списке вместе, чтобы получить наш результат:
result <- do.call(rbind, all_sampled)
Как видно из конечного результата, так получилось, что каждая из четырех групп была выбрана один раз (это случайно - измените set.seed, чтобы получить разные результаты). Тем не менее, внутри групп явно были нарисованы дубликаты. Фактически, поскольку R предписывает уникальные имена строк во фрейме данных, их легко выбрать с помощью .1
, добавленного к дублирующимся именам строк. Если вам это не нравится, вы можете сбросить имена строк с помощью rownames(result) <- seq(nrow(result))
result
#> id group y
#> 4.14 5010 4 19
#> 4.14.1 5010 4 19
#> 4.11 5006 4 7
#> 4.13 5009 4 22
#> 1.3 1003 1 3
#> 1.3.1 1003 1 3
#> 1.2 1002 1 15
#> 3.9 4001 3 12
#> 3.9.1 4001 3 12
#> 2.5 3003 2 15
#> 2.5.1 3003 2 15
#> 2.6 3005 2 37
#> 2.7 3006 2 32
#> 2.5.2 3003 2 15
, созданных в 2020-02-15 с помощью пакета prex (v0. 3,0)