对 R 中的矩阵进行下采样
downsampling a matrix in R
我有一个相对高维 (100X500000) 的矩阵 Q,我想对其进行下采样。通过降采样,我会举例说明。
令Q=
1 4 9
3 2 1
和下采样大小= n。我想从一罐 sum(Q) = 20 个球中抽取 n 个球,每个球着色 6 种方式中的一种,对应于矩阵的不同索引对。就像我有 1 个颜色 A 的球,4 个颜色 B 的球,等等,我正在绘制 n 个球,没有替换。
我希望它以与矩阵相同的格式 returned。一个示例 return 值,例如 downsample(Q, 3) =
0 0 2
1 0 0
我的方法是尝试使用示例:
sample(length(as.vector(Q)), size=n, replace=FALSE, prob = as.vector(Q))
但是问题是,示例将 1:length(as.vector(Q)) 视为我拥有的所有球,所以我不能绘制超过 length(as.vector(Q)) 球,因为我不会更换我的球。
然后为了调整我的方法,我需要通过从这个向量中减去 1 来更新我的概率,并使用某种 for 循环一个一个地调用样本。这听起来不像是好的代码。
是否有更好的方法以 R 友好的方式执行此操作,而不是 for 循环方式?
效率有点低,但是如果 sum(Q)
不是 太大 你可以通过 disaggregating/replicating 向量然后采样来做到这一点,然后 reaggregating/tabulating.
Q <- setNames(c(1,4,9,3,2,1),LETTERS[1:6])
n <- 10
set.seed(101)
s0 <- sample(rep(names(Q),Q),
size=n,replace=FALSE)
Q2 <- table(factor(s0,levels=names(Q)))
## A B C D E F
## 1 2 5 1 0 1
我不确定你的矩阵结构。您可以使用 dim(Q2) <- dim(Q)
以与原始矩阵相同的顺序重新组织结果 ...
这是一种非常好的方法。您可以通过将 which(x <= cq)[1]
替换为专为 finding the first TRUE value.
构建的函数来提高其效率(如有必要)
Q = matrix(c(1, 4, 9, 3, 2, 1), nrow = 2)
set.seed(47)
samp = sample(sum(Q), size = 3)
cq = cumsum(Q)
inds = table(sapply(samp, function(x) which(x <= cq)[1]))
result = integer(length(Q))
result[as.integer(names(inds))] = inds
dim(result) = dim(Q)
# [,1] [,2] [,3]
# [1,] 0 2 0
# [2,] 0 0 1
我有一个相对高维 (100X500000) 的矩阵 Q,我想对其进行下采样。通过降采样,我会举例说明。
令Q=
1 4 9
3 2 1
和下采样大小= n。我想从一罐 sum(Q) = 20 个球中抽取 n 个球,每个球着色 6 种方式中的一种,对应于矩阵的不同索引对。就像我有 1 个颜色 A 的球,4 个颜色 B 的球,等等,我正在绘制 n 个球,没有替换。
我希望它以与矩阵相同的格式 returned。一个示例 return 值,例如 downsample(Q, 3) =
0 0 2
1 0 0
我的方法是尝试使用示例:
sample(length(as.vector(Q)), size=n, replace=FALSE, prob = as.vector(Q))
但是问题是,示例将 1:length(as.vector(Q)) 视为我拥有的所有球,所以我不能绘制超过 length(as.vector(Q)) 球,因为我不会更换我的球。
然后为了调整我的方法,我需要通过从这个向量中减去 1 来更新我的概率,并使用某种 for 循环一个一个地调用样本。这听起来不像是好的代码。
是否有更好的方法以 R 友好的方式执行此操作,而不是 for 循环方式?
效率有点低,但是如果 sum(Q)
不是 太大 你可以通过 disaggregating/replicating 向量然后采样来做到这一点,然后 reaggregating/tabulating.
Q <- setNames(c(1,4,9,3,2,1),LETTERS[1:6])
n <- 10
set.seed(101)
s0 <- sample(rep(names(Q),Q),
size=n,replace=FALSE)
Q2 <- table(factor(s0,levels=names(Q)))
## A B C D E F
## 1 2 5 1 0 1
我不确定你的矩阵结构。您可以使用 dim(Q2) <- dim(Q)
以与原始矩阵相同的顺序重新组织结果 ...
这是一种非常好的方法。您可以通过将 which(x <= cq)[1]
替换为专为 finding the first TRUE value.
Q = matrix(c(1, 4, 9, 3, 2, 1), nrow = 2)
set.seed(47)
samp = sample(sum(Q), size = 3)
cq = cumsum(Q)
inds = table(sapply(samp, function(x) which(x <= cq)[1]))
result = integer(length(Q))
result[as.integer(names(inds))] = inds
dim(result) = dim(Q)
# [,1] [,2] [,3]
# [1,] 0 2 0
# [2,] 0 0 1