Произвольная выборка для каждой группы, создание нового кадра данных, повторение до тех пор, пока не будут выбраны все объекты в группе

Я хочу выбрать один случайный сайт для каждого региона, создать новый фрейм данных и повторять эти процессы до тех пор, пока не будут отобраны все сайты. Таким образом, каждый фрейм данных НЕ будет содержать один и тот же сайт из одного региона.

Несколько регионов в моем реальном фрейме данных имеют больше сайтов (в регионе C 4 сайта), чем в других регионах. Я хочу удалить эти строки (возможно, я должен сделать это до создания нескольких фреймов данных).

Вот примерный фрейм данных (реальный имеет>100 регионов и> 10 сайтов на регион):

mydf <- read.table(header = TRUE, text = 'V1 V2 Region Site 
5 1 A X1
5 6 A X2
8 9 A X3
2 3 B X1
3 1 B X2
7 8 B X3
1 2 C X1
9 4 C X2
4 5 C X3
6 7 C X4')

Повторение следующего кода три раза создает кадры данных, которые содержат одинаковые сайты для данного региона (во второй и третьей таблицах есть сайт X2 для региона A).

do.call(rbind, lapply(split(mydf, mydf$Region), function(x) x[sample(nrow(x), 1), ]))

  V1 V2 Region Site
A  8  9      A   X3
B  2  3      B   X1
C  6  7      C   X4

V1 V2 Region Site
A  5  6      A   X2
B  7  8      B   X3
C  9  4      C   X2

  V1 V2 Region Site
A  5  6      A   X2
B  3  1      B   X2
C  6  7      C   X4

Не могли бы вы помочь мне создать несколько фреймов данных, чтобы все фреймы данных содержали все регионы, но каждый фрейм данных содержал уникальную комбинацию регион-сайт.

РЕДАКТИРОВАТЬ: Здесь ожидаемый результат. Чтобы получить их, в первой выборке случайным образом нарисуйте один сайт (строку) из каждого региона и создайте фрейм данных. Во второй выборке повторите тот же процесс, но нельзя создать один и тот же участок для данного региона. То, что я хочу, это независимые фреймы данных, которые содержат уникальную комбинацию Region-Site.

V1 V2 Region Site
5 1 A X1
7 8 B X3
1 2 C X1

V1 V2 Region Site
5 6 A X2
3 1 B X2
4 5 C X3

V1 V2 Region Site
8 9 A X3
2 3 B X1
9 4 C X2

2 ответа

Это сработало! Я не вижу флажок для принятия ответа, поэтому я делаю здесь.

Великий data.table пакет на самом деле делает это очень легко

# Turn mydf into a data.table 
library(data.table)
setDT(mydf)

# Shuffle the rows of the table
dt <- dt[sample(.N)]

# In case there are multiple rows for a given Region <-> Site pair,
# eliminate duplicates.
dt <- unique(dt, by = c('Region', 'Site'))

# Get the first sample from each region group
# Note: .SD refers to the sub-tables after grouping by Region
dt[, .SD[1], by=Region]

# Get the second and third sample from each region group
dt[, .SD[2], by=Region]
dt[, .SD[3], by=Region]

На самом деле, вы можете объединиться в одну строку, как предложил Фрэнк

library(data.table)
dt <- setDT(mydf)
dt <- unique(dt, by = c('Region', 'Site'))
dt[sample(.N), .SD[1:3], by = Region]
Другие вопросы по тегам