因子分层抽样

时间:2015-05-07 09:44:21

标签: r dataframe sampling

我有一个1000行的数据集,结构如下:

     device geslacht leeftijd type1 type2
1       mob        0       53     C     3
2       tab        1       64     G     7
3        pc        1       50     G     7
4       tab        0       75     C     3
5       mob        1       54     G     7
6        pc        1       58     H     8
7        pc        1       57     A     1
8        pc        0       68     E     5
9        pc        0       66     G     7
10      mob        0       45     C     3
11      tab        1       77     E     5
12      mob        1       16     A     1

我想制作80行的样本,由10行(type1 = A),10行(type1 = B)组成,依此类推。有没有人可以帮助他?

3 个答案:

答案 0 :(得分:10)

以下是我使用data.table

进行此操作的方法
library(data.table)
indx <- setDT(df)[, .I[sample(.N, 10, replace = TRUE)], by = type1]$V1
df[indx]
#     device geslacht leeftijd type1 type2
#  1:    mob        0       45     C     3
#  2:    mob        0       53     C     3
#  3:    tab        0       75     C     3
#  4:    mob        0       53     C     3
#  5:    tab        0       75     C     3
#  6:    mob        0       45     C     3
#  7:    tab        0       75     C     3
#  8:    mob        0       53     C     3
#  9:    mob        0       53     C     3
# 10:    mob        0       53     C     3
# 11:    mob        1       54     G     7
#...

或者更简单的版本

setDT(df)[, .SD[sample(.N, 10, replace = TRUE)], by = type1]

基本上我们从type1的每组中的行索引进行抽样(包括替换 - 因为每组中少于10行),然后通过该索引对数据进行子集化

dplyr类似,你可以做

library(dplyr)
df %>% 
  group_by(type1) %>%
  sample_n(10, replace = TRUE)

答案 1 :(得分:7)

Base R解决方案:

do.call(rbind,
        lapply(split(df, df$type1), function(i)
          i[sample(1:nrow(i), size = 10, replace = TRUE),]))

修改

@BrodieG建议的其他解决方案

with(DF, DF[unlist(lapply(split(seq(type), type), sample, 10, TRUE)), ])

with(DF, DF[c(sapply(split(seq(type), type), sample, 10, TRUE)), ])

答案 2 :(得分:5)

基地R的另一个选择:

df[as.vector(sapply(unique(df$type1), 
                    function(x){
                        sample(which(df$type1==x), 10, replace=T)
                    })), ]