Один из способов go об этом, который не использует уже сгенерированные вами случайные числа, но в остальном довольно короткий, состоит в том, чтобы использовать функцию random()
для выполнения случайного назначения непосредственно для you:
DF1 <- data.frame(
ID = 1:7,
Class = c(1, 1, 2, 1, 2, 3, 1),
Random = c(0.65, 0.23, 0.45, 0.11, 0.89, 0.12, 0.9)
)
DF1 <- DF1[order(DF1$Class), ] #EDIT: need this for the code to behave properly!
DF2 <- data.frame(
Class = c(1, 1, 1, 2, 3, 3),
Group = c("Apples", "Hammer", "Car", "Building", "Computer", "Hammer"),
Share = c(0.5, 0.25, 0.25, 1, 0.5, 0.5),
Share_2 = c(0.5, 0.75, 1, 1, 0.5, 1)
)
set.seed(12345) # this is for reproducibility; you can choose any number here
DF3 <- DF1
DF3$Group <- unlist(sapply(unique(DF1$Class), function(x) {
with(DF2[DF2$Class == x, ],
sample(Group, size = sum(DF3$Class == x),
prob = Share, replace = TRUE))
}))
Работа извне внутри: параметр sapply
играет, по сути, роль for
l oop. Он начинается с просмотра всех уникальных записей в DF1$Class
. Для каждого из них (называемого x
) он вырезает кусок DF2
, соответствующий части, в которой Class
равно x
, а затем фокусируется только на этом фрагменте DF2
- это что здесь делает функция with()
.
Основная идея - использовать sample()
. Мы рисуем объекты для выборки из столбца Group
в DF2
, рисуем соответствующее количество выборок (отмеченных параметром size
), устанавливаем вероятности в соответствии со столбцом Share
из DF2
и рисуем с заменой. Все это имеет смысл, потому что мы находимся внутри функции with()
; мы уже ограничили наше внимание не только DF2
, но только фрагментом DF2
, соответствующим Class == x
.
Функция unlist()
используется, потому что вывод функции sapply()
список в данном случае, и мы хотим, чтобы он был просто вектором; затем мы просто приклеиваем этот вектор непосредственно к кадру данных DF3
, который в противном случае является идентичной копией DF1
.
EDIT: Я добавил сортировку строк DF1
, что необходимо для этого решения.