创建一个循环以获取满足条件的分组数据中的样本

时间:2019-07-05 09:15:09

标签: r loops sample

我有一个数据框,其中数据按ID分组。我需要知道每个组中10%的单元格是多少,以便在样本中选择此数字,但是此样本应选择EP为1的单元格。

我尝试做一个嵌套的For循环:一个是要知道每个组的单元格数量为10%,另一个是要采样的数量更大的单元格,以满足条件EP == 1

x <- data.frame("ID"=rep(1:2, each=10),"EP" = rep(0:1, times=10))
x
   ID EP
1   1  0
2   1  1
3   1  0
4   1  1
5   1  0
6   1  1
7   1  0
8   1  1
9   1  0
10  1  1
11  2  0
12  2  1
13  2  0
14  2  1
15  2  0
16  2  1
17  2  0
18  2  1
19  2  0
20  2  1

for(j in 1:1000){
  for (i in 1:nrow(x)){
    d <- x[x$ID==i,]
    npix <- 10*nrow(d)/100
  }
  r <- sample(d[d$EP==1,],npix)
  print(r)
}
data frame with 0 columns and 0 rows
data frame with 0 columns and 0 rows
data frame with 0 columns and 0 rows
.
.
.
until 1000

我想获取此数据帧,其中每个样本都位于x的新列中,并且所采样的单元格为“ 1”:

   ID EP s1 s2....s1000
1   1  0 0  0 ....
2   1  1 0  1
3   1  0 0  0
4   1  1 0  0
5   1  0 0  0
6   1  1 0  0
7   1  0 0  0
8   1  1 0  0
9   1  0 0  0
10  1  1 1  0
11  2  0 0  0
12  2  1 0  0
13  2  0 0  0
14  2  1 0  1
15  2  0 0  0
16  2  1 0  0
17  2  0 0  0
18  2  1 1  0
19  2  0 0  0
20  2  1 0  0

看到S1和s2中的每个1是被采样的细胞,并且对应于满足条件EP == 1的每组(1、2)中10%的细胞。

2 个答案:

答案 0 :(得分:2)

您可以尝试

set.seed(1231)
x <- data.frame("ID"=rep(1:2, each=10),"EP" = rep(0:1, times=10))

library(tidyverse)
x %>% 
  group_by(ID) %>% 
  mutate(index= ifelse(EP==1, 1:n(),0)) %>% 
  mutate(s1 = ifelse(index %in% sample(index[index!=0], n()*0.1), 1, 0)) %>% 
  mutate(s2 = ifelse(index %in% sample(index[index!=0], n()*0.1), 1, 0))
# A tibble: 20 x 5
# Groups:   ID [2]
      ID    EP index    s1    s2
   <int> <int> <dbl> <dbl> <dbl>
 1     1     0     0     0     0
 2     1     1     2     0     0
 3     1     0     0     0     0
 4     1     1     4     0     0
 5     1     0     0     0     0
 6     1     1     6     1     1
 7     1     0     0     0     0
 8     1     1     8     0     0
 9     1     0     0     0     0
10     1     1    10     0     0
11     2     0     0     0     0
12     2     1     2     0     0
13     2     0     0     0     0
14     2     1     4     0     1
15     2     0     0     0     0
16     2     1     6     0     0
17     2     0     0     0     0
18     2     1     8     0     0
19     2     0     0     0     0
20     2     1    10     1     0

答案 1 :(得分:1)

我们可以编写一个函数,为每个ID给我们1,即10%,并将其放在EP = 1处。

library(dplyr)
 rep_func <- function() {
   x %>%
    group_by(ID) %>%
    mutate(s1 = 0,
           s1 = replace(s1, sample(which(EP == 1), floor(0.1 * n())), 1)) %>%
    pull(s1)
}

然后使用replicate重复n

n <- 5
x[paste0("s", seq_len(n))] <- replicate(n, rep_func())

x
#   ID EP s1 s2 s3 s4 s5
#1   1  0  0  0  0  0  0
#2   1  1  0  0  0  0  0
#3   1  0  0  0  0  0  0
#4   1  1  0  0  0  0  0
#5   1  0  0  0  0  0  0
#6   1  1  1  0  0  1  0
#7   1  0  0  0  0  0  0
#8   1  1  0  1  0  0  0
#9   1  0  0  0  0  0  0
#10  1  1  0  0  1  0  1
#11  2  0  0  0  0  0  0
#12  2  1  0  0  1  0  0
#13  2  0  0  0  0  0  0
#14  2  1  1  1  0  0  0
#15  2  0  0  0  0  0  0
#16  2  1  0  0  0  0  1
#17  2  0  0  0  0  0  0
#18  2  1  0  0  0  1  0
#19  2  0  0  0  0  0  0
#20  2  1  0  0  0  0  0