R. 样本行遵循条件(在一个取值范围内随机;在另一个取值范围内固定)

R. Sample rows following conditions (at random within a range of values; fixed within another range of values)

我有一个这样的数据框A:

SNP X Y
rs1 5 aa
rs2 1 bb
rs3 6 aa
rs4 2 bb
rs7 11 ft
rs8 3 hg
rs9 1.2 ff
rs10 2.2 cc
rs11 2.2 yh
rs362 3.2 hyu

使用 R,我想根据 2 个条件对行进行采样:(1) 保留 X >= 5 中值的所有行; (2) 随机抽样,不替换 X > 0 和 X < 5 的 2 行。我会得到这样的结果:

SNP X Y
rs1 5 aa
rs2 1 bb
rs3 6 aa
rs7 11 ft
rs9 1.2 ff
rs362 3.2 hyu

我正在尝试类似的东西:

A.1 = A[A$X >= 5,]
B.2 = A[sample(nrow(A), 2), ]

我们可以使用which函数:

set.seed(1) # reproducible
d[c(which(d$X >= 5), sample(which(d$X > 0 & d$X < 5), 2)),]

  SNP    X  Y
1 rs1  5.0 aa
3 rs3  6.0 aa
5 rs7 11.0 ft
2 rs2  1.0 bb
7 rs9  1.2 ff

which(d$X >= 5) 查找数据中 X >= 5 的行。然后,我们再次使用 which 找到 X > 0 & X < 5 的行,并从这些行中找到 sample 2 。然后我们将这两个行索引向量连接在一起。

数据

d <- structure(list(SNP = c("rs1", "rs2", "rs3", "rs4", "rs7", "rs8", 
                            "rs9", "rs10", "rs11", "rs362"), 
                    X = c(5, 1, 6, 2, 11, 3, 1.2, 
                          2.2, 2.2, 3.2),
                    Y = c("aa", "bb", "aa", "bb", "ft", "hg", "ff", 
                          "cc", "yh", "hyu")), 
               class = "data.frame", 
               row.names = c(NA, -10L))

使用 dplyr 你可以这样做:

library(dplyr)

A.1 <- A %>% filter(X >= 5)
B.2 <- A %>% anti_join(A.1) %>% slice_sample(n = 2)
#For dplyr < 1.0.0 use sample_n
#B.2 <- A %>% anti_join(A.1) %>% sample_n(2)
A.1
#  SNP  X  Y
#1 rs1  5 aa
#2 rs3  6 aa
#3 rs7 11 ft

B.2
#   SNP   X  Y
#1 rs11 2.2 yh
#2  rs2 1.0 bb

A.1 包含 X >= 5 所在的所有行。然后,我们使用 anti_joinA 中获取 A.1 中不存在的所有行,并从中抽取 2 行。如果你想合并两个数据框,你可以使用 bind_rows(A.1, B.2).