通过 ID 和 R 中的某个因子分布创建一个随机子样本

lol*_*ily 6 random merge r subset sampling

我正在使用 R 并拥有以下数据集,其中包含从书中取出的句子,并包含有关书籍 ID、封面颜色(颜色)以及与相应书籍匹配的句子 ID 的数据。

My dataset
    Book ID| sentence ID| Colour      | Sentences
    1      | 1          | Blue        | Text goes here
    1      | 2          | Blue        | Text goes here
    1      | 3          | Blue        | Text goes here
    2      | 4          | Red         | Text goes here
    2      | 5          | Red         | Text goes here
    3      | 6          | Green       | Text goes here
    4      | 7          | Orange      | Text goes here
    4      | 8          | Orange      | Text goes here
    4      | 9          | Orange      | Text goes here
    4      | 10         | Orange      | Text goes here
    4      | 11         | Orange      | Text goes here
    5      | 12         | Blue        | Text goes here
    5      | 13         | Blue        | Text goes here
    6      | 14         | Red         | Text goes here
    6      | 15         | Red         | Text goes here
    .
Run Code Online (Sandbox Code Playgroud)

我想在以下条件下采用四个随机子样本(每个包含原始数据的 25%):

1)书本颜色的分布应与原始数据集中的分布保持一致。如果有 10% 的蓝皮书,这也应该反映在子样本中

2) 子样本不应按行数(即句子 ID)进行/拆分,而应按"Book ID" 进行。这意味着如果对图书 ID 4 进行采样,则所有句子 7、8、9、10、11 都应在示例数据集中。

3) 此外,每个书籍 ID 应该只在 4 个子样本之一中 - 这意味着如果我决定合并所有 4 个子样本,我想再次以原始数据集结束。

以上述方式拆分我的数据集的最佳解决方案是什么?

Geo*_*ery 2

这是简短的版本:

library(tidyverse)

df <- tribble(
    ~Book_ID, ~sentence_ID, ~Colour, ~Sentences
    ,1      , 1, "Blue", "Text goes here"
    ,1      , 2, "Blue", "Text goes here"
    ,1      , 3, "Blue", "Text goes here"
    ,2      , 4, "Red", "Text goes here"
    ,2      , 5, "Red", "Text goes here"
    ,3      , 6, "Green", "Text goes here"
    ,4      , 7, "Orange", "Text goes here"
    ,4      , 8, "Orange", "Text goes here"
    ,4      , 9, "Orange", "Text goes here"
    ,4      , 10, "Orange", "Text goes here"
    ,4      , 11, "Orange", "Text goes here"
    ,5      , 12, "Blue", "Text goes here"
    ,5      , 13, "Blue", "Text goes here"
    ,6      , 14, "Red", "Text goes here"
    ,6      , 15, "Red", "Text goes here"
)

df %>%
    left_join(
        df %>%
            distinct(Book_ID, Colour) %>%
            group_by(Colour) %>%
            mutate(sub_sample = sample.int(4, size = n(), replace = TRUE))
        , by = c("Book_ID", "Colour"))
Run Code Online (Sandbox Code Playgroud)

这会给你:

# A tibble: 15 x 5
   Book_ID sentence_ID Colour Sentences        sub_sample
     <dbl>       <dbl> <chr>  <chr>                 <int>
 1       1           1 Blue   "Text goes here"          3
 2       1           2 Blue   "Text goes here"          3
 3       1           3 Blue   "Text goes here"          3
 4       2           4 Red    "Text goes here"          1
 5       2           5 Red    "Text goes here"          1
 6       3           6 Green  "Text goes here"          1
 7       4           7 Orange "Text goes here"          2
 8       4           8 Orange "Text goes here"          2
 9       4           9 Orange "Text goes here"          2
10       4          10 Orange "Text goes here"          2
11       4          11 Orange "Text goes here"          2
12       5          12 Blue   "Text goes here"          2
13       5          13 Blue   "Text goes here"          2
14       6          14 Red    "Text goes here"          3
15       6          15 Red    "Text goes here"          3
Run Code Online (Sandbox Code Playgroud)

以及代码的简短解释

让我们从嵌套部分开始

# take the dataframe
df %>%
    # ...and extract the distinct combinations of book and colour
    distinct(Book_ID, Colour) %>%
    # and now for each colour...
    group_by(Colour) %>%
    # ...provide random numbers from 1 to 4
    mutate(sub_sample = sample.int(4, size = n(), replace = TRUE))
Run Code Online (Sandbox Code Playgroud)

按颜色分组可确保每个样本中的颜色分布相同。

其结果现在被left_join编辑到我们之前“区分”的两列上的原始数据帧 - 这确保了不会有重复项。


补充一

为了在子样本中具有相同的颜色分布,您当然需要每种颜色都有足够数量的书籍。因此,举例来说,只有 20 本不同的绿色书籍可以保证以不同的方式分发。在这种情况下,您可能希望对采样的颜色进行“分组”。然而,这是一个统计问题,显然超出了编程论坛的范围。