【问题标题】:Resample groups of rows based on a grouping variable in R根据 R 中的分组变量对行组重新采样
【发布时间】:2016-02-23 06:46:46
【问题描述】:

我对 R 比较陌生,如果这是一个愚蠢/明显的问题,我深表歉意!我有兴趣创建一个新数据集,该数据集由从更大的数据集中重新采样并替换的行集合组成。

我拥有的数据集看起来像这样,每个分组变量多行。

> df <- data.frame(value=c(1:5,1:4,1:3),ID=c(rep(1,5),rep(2,4),rep(3,3)))
> df
   value ID
1      1  1
2      2  1
3      3  1
4      4  1
5      5  1
6      1  2
7      2  2
8      3  2
9      4  2
10     1  3
11     2  3
12     3  3

我想做的是创建一个基于分组变量重新采样(带替换)的新数据集。所以重新采样的数据集可能看起来像这样:

   value ID
1      1  1
2      2  1
3      3  1
4      4  1
5      5  1
6      1  3
7      2  3
8      3  3
9      1  1
10     2  1
11     3  1
12     4  1
13     5  1

感谢您的任何建议!

【问题讨论】:

  • 你需要df[sample(nrow(df)), ]吗?
  • @RonakShah,感谢您的建议。我需要它在对给定 ID 进行采样时获取所有行(即,对行块进行采样)。
  • 如果我理解你的问题,使用库dplyr 和分组,你可以尝试这样的事情:df %&gt;% group_by(ID) %&gt;% slice(sample(n(), 3, replace = TRUE))。这适用于固定数量的采样。否则,你需要用rbind写一个循环。
  • 谢谢,@Gopala。如示例中所示,行数确实因分组 ID 而异。关于 rbind 循环可能是什么样子的任何提示?
  • 见下文....三种不同的解决方案来实现我希望是您想要的结果。

标签: r random-sample


【解决方案1】:

对于每个 ID 值采样不同数量的行,您可以尝试这样的操作(假设 ID 值具有少量唯一值):

result <- NULL
result <- rbind(result, df[sample(row.names(df[df$ID == 1, ]), 10, replace = TRUE), ])
result <- rbind(result, df[sample(row.names(df[df$ID == 2, ]), 5, replace = TRUE), ])
result <- rbind(result, df[sample(row.names(df[df$ID == 3, ]), 3, replace = TRUE), ])
row.names(result) <- seq(1:nrow(result))

如果有许多 ID 值,您可能希望使用一个循环,其中包含所需的每个 ID 值的样本数。例如,如果有六个 ID 值,每个 ID 对应的样本数分别为 10、5、3、7、8 和 2,则可以这样做:

nsamples <- c(10, 5, 3, 7, 8, 2)
result <- NULL
for (i in 1:length(nsamples)) {
  result <- rbind(result, df[sample(row.names(df[df$ID == i, ]), nsamples[i], replace = TRUE), ])
}
row.names(result) <- seq(1:nrow(result))

无论哪种情况,您最终都会得到如下输出:

   value ID
1      1  1
2      4  1
3      1  1
4      4  1
5      2  1
6      3  1
7      1  1
8      1  1
9      4  1
10     2  1
11     2  2
12     3  2
13     1  2
14     3  2
15     1  2
16     3  3
17     2  3
18     1  3

使用上面建议的 dplyr 解决方案,您还可以对每个 ID 值的可变样本数执行类似的操作(它还需要预先指定向量中每个对应 ID 的样本数):

library(dplyr)
nsamples <- c(10, 5, 3)
df %>% group_by(ID) %>% slice(sample(n(), nsamples[ID], replace = TRUE))

【讨论】:

  • 这没有成功完成所要求的。它对给定 ID 的行的随机子集进行采样。该问题询问如何对 ID 进行替换采样,每次都取所有具有该 ID 的行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多