我有一个如下所示形式的数据框。这些病例已预先分为不同人群的亚组,包括单身人士。我正在尝试编写一些代码,这些代码将从数据帧中采样(不替换)任何指定数量的行,但在集群中尽可能均匀地分布。
> testdata
Cluster Name
1 1 A
2 1 B
3 1 C
4 2 D
5 3 E
6 3 F
7 3 G
8 3 H
9 4 I
10 5 J
11 5 K
12 5 L
13 5 M
14 5 N
15 6 O
16 7 P
17 7 Q
例如,如果我要求一个 3 行的样本,我想从随机的 3 个集群中抽取一个随机行(即不是每次第 1-3 行集群,尽管这是一个有效的结果)。
可接受的例子:
> testdata_subset
Cluster Name
1 1 A
5 3 E
12 5 L
> testdata_subset
Cluster Name
6 3 F
14 5 N
15 6 O
不正确的例子:
> testdata_subset
Cluster Name
6 3 F
8 3 H
13 5 M
同样的想法适用于示例数据中的样本大小为 7(每个集群 1 个)。对于更高的样本量,我想尽可能均匀地从每个集群中抽取,然后均匀地跨越具有未采样行的剩余集群,依此类推,直到指定的行数被采样。
我知道如何不加选择地对 N 行进行采样:
testdata[sample(nrow(testdata), N),]
但这不考虑集群。我还曾经plyr
对每个集群随机抽样 N 行:
ddply(testdata,"Cluster", function(z) z[sample(nrow(z), N),])
但是,只要您要求的行数超过集群中的行数(即如果 N > 1),就会失败。然后我添加了一个 if/else 语句来开始处理它:
numsamp_per_cluster <- 2
ddply(testdata,"Cluster", function(z) if (numsamp_per_cluster > nrow(z)){z[sample(nrow(z), nrow(z)),]} else {z[sample(nrow(z), numsamp_per_cluster),]})
这有效地将要求的样本大小限制为每个集群的大小。但在这样做的过程中,它失去了对整体样本量的控制。我希望(但开始怀疑)有一种优雅的方法使用dplyr
或类似的包可以进行这种半随机抽样。无论哪种方式,我都在努力将这些元素联系在一起并解决问题。