【问题标题】:Subset a data frame by randomly selecting values based on two columns通过基于两列随机选择值来子集数据框
【发布时间】:2016-03-10 05:03:55
【问题描述】:

我有一个数据框,我想通过随机选择 25 个基于 spp == cat 的 ID 值和 25 个基于 spp == dog 的 ID 值来进行子集化。

这是我的示例数据:

ID  spp category    prop
1   cat small_mam   0.99
2   cat small_mam   0.8
2   cat birds       0.15
3   dog large_mam   1
4   dog med_mam     0.4
4   dog emu         0.6
10  dog med_mam     0.8
10  dog birds       0.2
12  dog reptiles    1
13  dog large_mam   1
14  dog large_mam   1
15  dog large_mam   1
27  cat birds       0.2
28  cat small_mam   1
29  cat small_mam   0.75
29  cat birds       0.25
30  cat small_mam   0.7
30  cat birds       0.2

spp 的 ID 值是唯一的,这意味着 cat 和 dog 永远不会具有相同的 ID 值。 ID 范围从 1 到 696,但不一定是唯一的,这是因为 ID 最多可以由 7 个类别组成,因此为每个物种随机子设置 25 行是行不通的。

这个问题背后的背景是,我将抽取 1000 个随机样本,包含 25 只猫和 25 只狗的粪便(UID = 粪便 ID 号),用于使用 package(pgirmess) 中的 piankabio 函数进行饮食重叠的引导计算。

提前感谢您的帮助。

我使用的是 R 版本 3.1.3

【问题讨论】:

    标签: r random subset


    【解决方案1】:

    使用,您可以这样做:

    library(data.table)
    subdf <- setDT(mydf)[, sample(ID, 5), by = spp]
    

    根据您提供的示例数据:

    > subdf
        spp V1
     1: cat 27
     2: cat 30
     3: cat  2
     4: cat 28
     5: cat 30
     6: dog 10
     7: dog 14
     8: dog 12
     9: dog  4
    10: dog 15
    

    当你想保留所有列时(我想你想这样做),你可以这样做:

    subdf <- setDT(mydf)[, .SD[sample(.N, 5)], by = spp]
    

    给出:

    > subdf
        spp ID  category prop
     1: cat 29 small_mam 0.75
     2: cat  1 small_mam 0.99
     3: cat  2     birds 0.15
     4: cat 30 small_mam 0.70
     5: cat 28 small_mam 1.00
     6: dog 14 large_mam 1.00
     7: dog 15 large_mam 1.00
     8: dog 13 large_mam 1.00
     9: dog 10     birds 0.20
    10: dog  4   med_mam 0.40
    

    注意:出于解释原因,我使用了 5 个样本,因为示例数据集不足以抽取 25 个样本。


    针对您的评论,您可以通过以下方式实现:

    setDT(mydf)
    set.seed(4321)
    newdf <- mydf[mydf[, .(ID = sample(unique(ID), 5)), by = spp], on = c("spp", "ID")]
    

    给出:

    > newdf
        ID spp  category prop
     1: 27 cat     birds 0.20
     2: 29 cat small_mam 0.75
     3: 29 cat     birds 0.25
     4:  2 cat small_mam 0.80
     5:  2 cat     birds 0.15
     6:  1 cat small_mam 0.99
     7: 28 cat small_mam 1.00
     8: 14 dog large_mam 1.00
     9: 13 dog large_mam 1.00
    10: 15 dog large_mam 1.00
    11:  4 dog   med_mam 0.40
    12:  4 dog       emu 0.60
    13: 12 dog  reptiles 1.00
    

    解释:使用mydf[, .(ID = sample(unique(ID), 5)), by = spp],您可以为spp 的每个类别创建一个具有5 个唯一ID 的索引data.table。然后在 sppID 上进行连接,使用这个 index-data.table 选择具有这些 ID 的 mydf 部分。

    【讨论】:

    • 谢谢,这非常接近我的需要,唯一的问题是它总是只返回 50 行(如果我使用 25 而不是 5)。我真正需要的是,如果选择的 ID 值不是唯一的(因为一个 ID 值可以有多个类别),那么我需要在子集中返回具有该 ID 值的所有行。每个 ID 值对应一个单独的 scat,我需要该子集来表示 25 个 cat scats 和 25 个 dog scats,因此子集数据帧可能会大于 50 行。我希望这是有道理的。我意识到这可能在原始帖子中并不清楚。
    • 是的,这正是我所需要的!非常感谢,谢谢!
    猜你喜欢
    • 2016-02-20
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    相关资源
    最近更新 更多