user3594490
user3594490

Reputation: 1999

R: Stratified random sample proportion of unique ID's by grouping variable

With the following sample dataframe I would like to draw a stratified random sample (e.g., 40%) of the ID's "ID" from each level of the factor "Cohort":

data<-structure(list(Cohort = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), ID = structure(1:20, .Label = c("a1 ", 
"a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "b10", "b11", 
"b12", "b13", "b14", "b15", "b16", "b17", "b18", "b19", "b20"
), class = "factor")), .Names = c("Cohort", "ID"), class = "data.frame", row.names = c(NA, 
-20L))

I only know how to draw a random number of rows using the following:

library(dplyr)
data %>% 
group_by(Cohort) %>%
sample_n(size = 10)

But my actual data are longitudinal so I have multiple cases of the same ID within each cohort and several cohorts of different sizes, thus the need to select a proportion of unique ID's. Any assistance would be appreciated.

Upvotes: 6

Views: 2588

Answers (2)

bramtayl
bramtayl

Reputation: 4024

Why not

library(dplyr)

data %>%
  select(ID, Cohort) %>%
  distinct %>%
  group_by(Cohort) %>%
  sample_frac(0.4) %>%
  left_join(data)

Upvotes: 5

eipi10
eipi10

Reputation: 93851

Here's one way:

data %>% group_by(Cohort) %>%
  filter(ID %in% sample(unique(ID), ceiling(0.4*length(unique(ID)))))

This will return all rows containing the randomly sampled IDs. In other words, I'm assuming you have measurements that go with each row and that you want all the measurements for each sampled ID. (If you just want one row returned for each sampled ID then @bramtayl's answer will do that.)

For example:

data = data.frame(rbind(data, data), value=rnorm(2*nrow(data)))

data %>% group_by(Cohort) %>%
  filter(ID %in% sample(unique(ID), ceiling(0.4*length(unique(ID)))))

   Cohort     ID       value
    (int) (fctr)       (dbl)
1       1    a1  -0.92370760
2       1     a2 -0.37230655
3       1     a3 -1.27037502
4       1     a7 -0.34545295
5       2    b14 -2.08205561
6       2    b17  0.31393998
7       2    b18 -0.02250819
8       2    b19  0.53065857
9       2    b20  0.03924414
10      1    a1  -0.08275011
11      1     a2 -0.10036822
12      1     a3  1.42397042
13      1     a7 -0.35203237
14      2    b14  0.30422865
15      2    b17 -1.82008014
16      2    b18  1.67548568
17      2    b19  0.74324596
18      2    b20  0.27725794

Upvotes: 8

Related Questions