在不同类别中随机选择的不同大小的组

时间:2015-01-27 19:11:50

标签: r

我有一个如此困难的问题(至少对我而言)我花了2个小时才写出来。完全不可能自己编程。我试着非常清楚,如果我没有,我很抱歉。我在excel中以非常质朴的方式这样做,但我真的需要编程。 我有像这样的data.frame

id_pix id_lote clase   f1   f2
45       4      Sg    2460 2401
46       4      Sg    2620 2422
47       4      Sg    2904 2627
48       5      M     2134 2044
49       5      M     2180 2104
50       5      M     2127 2069
83      11      S     2124 2062
84      11      S     2189 2336
85      11      S     2235 2162
86      11      S     2162 2153
87      11      S     2108 2124

17451“id_pixel”(行),2080“id_lote”和9“clase”

这是每个“clase”的“id_lote”计数(v1是id_lote计数)

 clase   v1
1:     S 1099
2:     P  213
3:    Sg  114
4:     M  302
5:   Alg   27
6:    Az   77
7:    Po  228
8:   Cit   13
9:    Ma    7

我需要在“clase”中随机拆分“id_lote”。我的意思是我有1099“id_lote”用于“S”“clase”,即9339“id_pixel”(行),我想随机选择50%的“id_lote”,即x“id_pixel”(行)。考虑到每个“clase”的大小(“id_lote”的数量)不同,为每个“clase”执行此操作。我也希望能够改变选择的大小(50%,30%等)。我还想保留未选择的“id_lote”集。我希望有人可以帮助我!

这是可重现的例子

这是2 clase(S和Az)的数据,6 id_lote和13 id_pixel

id_pix  id_lote clase   f1  f2
1       1        S    2909  2381
2       1        S    2515  2663
3       1        S    2628  3249
30      2        S    3021  2985
31      2        S    3020  2596
71      9        S    4725  4404
72      9        S    4759  4943
75      11       S    2728  2225
218     21       Az   4830  3007
219     21       Az   4574  2761
220     21       Az   5441  3092
1155    126      Az   7209  2449
1156    126      Az   7035  2932

,结果可能是:

id_pix  id_lote clase   f1  f2
    1       1        S    2909  2381
    2       1        S    2515  2663
    3       1        S    2628  3249
    75      11       S    2728  2225
    1155    126      Az   7209  2449
    1156    126      Az   7035  2932

50%的id_lote是在clase“S”(4个id_lote中的2个)中随机选择的,但所有id_lote中的id_pixel都被保留了。对于clase“Az”也是如此,随机选择了一个id_lote(在这种情况下为2个中的1个)并且所选id_lote中的所有id_pixel都被保留了。

colemand77提出了什么帮助了很多。我认为dplyr包对此有用,但我认为如果我这样做

df %>%
group_by(clase, id_lote) %>%
sample_frac(.3, replace = FALSE)

我得到每个clase的30%的数据但不按我需要的id_lote分组!我的意思是选择了30%的行(id_pixel)而不是id_lote。 我希望这个例子有助于理解我想做的事情并使其对每个人都有用。如果我第一次不够清楚,我很抱歉。 非常感谢!

1 个答案:

答案 0 :(得分:3)

第一眼我会说dplyr包是你的朋友。

df %>%
group_by(clase, id_lote) %>%
sample_frac(.3, replace = FALSE)

因此,您首先使用group_by()并包含要从中抽样的分组级别,然后使用sample_frac对每个组所需的结果进行采样。 我尽可能地告诉你这就是你所要求的。如果没有,请考虑重新陈述您的问题,以包含可重复的示例或澄清。欢呼声。

要“保留”未选中的成员,我会添加一列唯一ID,并使用反连接anti_join()(也来自dplyr包)来查找不相同的ID两个data.frames(采样结果和原始结果)。


## Update ##

我相信,我现在明白了。认为这是一个两步过程...... 1)你想从每个clase中选择id_lote的x%(例子中为50)并返回那些id_lote #s(我假设多个clase不存在给定的id_lote?) 2)您希望在一个data.frame中看到与每个id_lote对应的所有id_pixel,所有这些都在一起。

我已将其分解为多个步骤以进行说明,而不是因为它是最快/最漂亮的。

原始数据:(无法将数据读入R中。)

df<-data.frame(id_pix = c(1:200), 
           id_lote = sample(1:20,200, replace = TRUE),
           clase = sample(letters[seq_along(1:10)], 200, replace = TRUE),
           f1 = sample(1000:2000,200, replace = TRUE),
           f2 = sample(2000:3000,200, replace = TRUE))

1)找出哪个id_lote对应哪个clase - 为此我们使用dplyr summarise函数并将其存储在变量中

summary<-df %>%
  ungroup() %>%
  group_by(clase, id_lote) %>%
  summarise()

返回:

Source: local data frame [125 x 2]
Groups: clase

   clase id_lote
1      a       1
2      a       2
3      a       4
4      a       5
5      a       6
6      a       7
7      a       8
8      a       9
9      a      11
10     a      12
..   ...     ...

然后我们采样以获得每个clase的30%id_lote ..

sampled_summary <- summary %>%
  group_by(clase) %>%
  sample_frac(.3,replace = FALSE) 

所以这个结果是一个包含两列的数据表,(clase和id_lote),每个clase显示了30%的id_lotes。

2)好了所以现在我们从每个类中随机选择了id_lotes,而不是与该类相关联的id_pix。为实现此目的,我们执行join以获取相应的完整数据集,包括id_pix等。

result <- sampled_summary %>%
  left_join(df)

上面的内容是数据集的副本,所以如果你有一个实质性的数据集,你可以一次性完成所有这些:

result <- df %>%
  ungroup() %>%
  group_by(clase, id_lote) %>%
  summarise() %>%
  group_by(clase) %>%
  sample_frac(.5,replace = FALSE) %>%
  left_join(df)

如果这不能满足您的需求,请告诉我们,我们将再次采取行动。