我的计数矩阵具有许多零元素:
my.matrix <- as.data.frame(matrix(rbinom(100 * 1000, 1, 0.5), ncol = 100, nrow = 1000))
(实际上,非零整数的范围在1到12,000之间,但我找不到一个更好的例子。我的数据集不仅包含0和1(。
我想随机选择至少x n的n行(n = 100,例如(,但不超过y非零元素:
n = number of randomly selected rows
x = minimum amount of non-zero elements in a row
y = maximum amount of non-zero elements in a row
该怎么做?预先感谢您!
为可重复的随机数据设置种子:
set.seed(2)
my.matrix <- as.data.frame(matrix(rbinom(100 * 1000, 1, 0.5), ncol = 100, nrow = 1000))
诸如apply
和rowSums
之类的功能将将数据转换为matrix
。如果您包含的列是character
,则所有内容都将被转换,并且事情可能不会按照您的意愿行事。isnum
的使用仅仅是为了确保您不会无意中包含它(即使该实际示例数据没有错(:
isnum <- sapply(my.matrix, is.numeric)
sums <- rowSums(my.matrix[,isnum] != 0)
head(sums)
# [1] 51 60 53 45 42 56
table(sums)
# sums
# 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
# 2 2 1 7 11 20 21 37 36 49 46 64 72 71 59 79 72 77 76 52 48 33 21 14 11 10
# 62 63 64 70
# 1 5 2 1
从这里,只需手动子集范围。
my.matrix[ 37 < sums & sums < 40, 1:4 ]
# V1 V2 V3 V4
# 69 0 0 1 1
# 202 1 0 0 1
# 228 0 1 0 0
# 293 1 0 1 0
# 306 0 1 0 0
# 363 0 1 1 0
# 810 0 0 1 1
# 890 1 0 1 1
您也可以使用dplyr::between
或data.table::between
来实现更加成功的代码,尽管它不会在此上增加任何功能。
至于采样,一旦获得此信息,它是直接的抽样:
ind <- which(37 < sums & sums < 40)
ind <- sample(ind, min(length(ind), 100))
my.matrix[ ind, 1:4 ]
# V1 V2 V3 V4
# 363 0 1 1 0
# 202 1 0 0 1
# 228 0 1 0 0
# 890 1 0 1 1
# 306 0 1 0 0
# 69 0 0 1 1
# 810 0 0 1 1
# 293 1 0 1 0
我做了max(...)
,以防您在生成的向量中少于100的。没有max
,您可能会看到cannot take a sample larger than the population when 'replace = FALSE'
。
如果您的数据是数字的,则使用矩阵粘上,并且不要将其逼入数据框架。转换类型的计算成本,在这种情况下,数据框架没有任何明显的优势。使用一些略有不同的数据:
set.seed(12345)
my.matrix <- matrix(sample(c(sample.int(12000, 90000, T), rep(0, 10000))),
ncol = 100,
nrow = 1000
)
获取由my.matrix != 0
创建的逻辑矩阵的行总和,对于非零值是正确的。然后设置上下阈值,在which
中进行比较,以获取所有至少包含x
和最多y
的行的索引子集您的数据框:
rs <- rowSums(my.matrix != 0)
x <- 85 # lower threshold
y <- 90 # upper threshold
my.matrix[sample(which(rs >= x & rs <= y), 100),]