R - 在采样时设置特定变量的等概率

时间:2015-01-07 16:16:11

标签: r

我有一个包含超过2百万个条目的数据集,我将其加载到数据框中。

我正在尝试抓取一部分数据。我需要大约10000个条目,但我需要在一个变量上以相同的概率选择条目。

这是str(data)我的数据:

'data.frame':   2685628 obs. of  3 variables:
$ category   : num  3289 3289 3289 3289 3289 ...
$ id: num  8064180 8990447 747922 9725245 9833082 ...
$ text    : chr  "text1" "text2" "text3" "text4" ...

你注意到我有3个变量:category,id和text。

我尝试了以下内容:

> sample_data <- data[sample(nrow(data),10000,replace=FALSE),]

当然这有效,但样本的概率如果不相等。以下是count(sample_data$category)的输出:

      x freq
1  3289  707
2  3401  341
3  3482  160
4  3502  243
5  3601 1513
6  3783  716
7  4029  423
8  4166   21
9  4178  894
10 4785   31
11 5108  121
12 5245 2178
13 5637  387
14 5946 1484
15 5977  117
16 6139  664

更新:以下是count(data$category)的输出:

  x   freq
1  3289 198142
2  3401  97864
3  3482  38172
4  3502  59386
5  3601 391800
6  3783 201409
7  4029 111075
8  4166   6749
9  4178 239978
10 4785   6473
11 5108  32083
12 5245 590060
13 5637  98785
14 5946 401625
15 5977  28769
16 6139 183258

但是当我尝试设置概率时,我得到以下错误:

> catCount <- length(unique(data$category))
> probabilities <- rep(c(1/catCount),catCount)
> train_set <- data[sample(nrow(data),10000,prob=probabilities),]
Error in sample.int(x, size, replace, prob) : 
incorrect number of probabilities

据我所知,样本函数是在行号之间随机挑选的,但我无法弄清楚如何将其与类别的概率联系起来。

问题:如何对类别变量以相同的概率对数据进行采样?

提前致谢。

1 个答案:

答案 0 :(得分:5)

我想你可以通过一些简单的基本R操作来做到这一点,不过你应该记住你在sample内使用概率,从而获得每个组合的精确金额'使用这种方法,虽然你可以足够接近足够大的样本。

这是一个示例数据

set.seed(123)
data <- data.frame(category = sample(rep(letters[1:10], seq(1000, 10000, by = 1000)), 55000))

然后

probs <- 1/prop.table(table(data$category)) # Calculating relative probabilities
data$probs <- probs[match(data$category, names(probs))] # Matching them to the correct rows
set.seed(123)
train_set <- data[sample(nrow(data), 1000, prob = data$probs), ] # Sampling
table(train_set$category) # Checking frequencies
#  a   b   c   d   e   f   g   h   i   j 
# 94 103  96 107 105  99 100  96 107  93 

修改:这是一个可能的data.table等效

library(data.table)
setDT(data)[, probs := .N, category][, probs := .N/probs]
train_set <- data[sample(.N, 1000, prob = probs)]

编辑#2:以下是使用@Khashaa和@docendodiscimus提供的dplyr软件包的非常好的解决方案

这个解决方案的好处是它在每个组中返回精确样本大小

library(dplyr)
train_set <- data %>% 
             group_by(category) %>% 
             sample_n(1000)

编辑#3: 似乎data.table相当于dplyr::sample_n

library(data.table)
train_set <- setDT(data)[data[, sample(.I, 1000), category]$V1]

这也会返回每个组中完全的样本大小