给定一个5x5矩阵:
dataset=matrix(cbind(c(1,1,2,2,0),
c(1,1,2,0,0),
c(0,0,0,1,0),
c(0,0,1,1,1),
c(1,2,3,4,0))
dataset
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 0 0 1
[2,] 1 1 0 0 2
[3,] 2 2 0 1 3
[4,] 2 0 1 1 4
[5,] 0 0 0 1 0我想要从矩阵的每一行中采样1个观测值,该行的采样值等于1,并且我想创建一个新矩阵,其中随机采样值在新矩阵中设置为True,所有其他值设置为false。下面提供了预期输出的示例:
1 2 3 4 5
1 FALSE TRUE FALSE FALSE FALSE
2 TRUE FALSE FALSE FALSE FALSE
3 FALSE FALSE FALSE TRUE FALSE
4 FALSE FALSE TRUE FALSE FALSE
5 FALSE FALSE FALSE TRUE FALSE 有没有人能帮我弄清楚怎么才能做到这点。
发布于 2019-02-19 09:35:52
这里有一个选项
# Courtesy of Hadley (avoids the "surprise" sample result when we have only one element)
# [http://r.789695.n4.nabble.com/using-quot-sample-quot-for-a-vector-of-length-1-td2299330.html]
resample <- function(x, ...) x[sample.int(length(x), ...)]
set.seed(2019)
t(apply(dataset, 1, function(x)
replace(rep(FALSE, length(x)), resample(which(x == 1), 1), TRUE)))
# [,1] [,2] [,3] [,4] [,5]
#[1,] FALSE FALSE FALSE FALSE TRUE
#[2,] FALSE TRUE FALSE FALSE FALSE
#[3,] FALSE FALSE FALSE TRUE FALSE
#[4,] FALSE FALSE FALSE TRUE FALSE
#[5,] FALSE FALSE FALSE TRUE FALSE为了重复性,我添加了一个固定的随机种子;从dataset的每一行中删除以随机抽样1。
样本数据
dataset=matrix(
c(1,1,2,2,0,1,1,2,0,0,0,0,0,1,0,0,0,1,1,1,1,2,3,4,0),
nrow = 5, ncol = 5)
dataset
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 1 0 0 1
#[2,] 1 1 0 0 2
#[3,] 2 2 0 1 3
#[4,] 2 0 1 1 4
#[5,] 0 0 0 1 0发布于 2019-02-19 09:41:42
如果我理解这个请求,那么这应该是一个有效的答案:
(dataset==1) * rbinom(length(dataset), 1, 0.5)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 0 0 0 1
[2,] 0 1 0 0 0
[3,] 0 0 0 1 0
[4,] 0 0 0 1 0
[5,] 0 0 0 1 0我的理解是,您只需要在与原始矩阵中的1相同的位置上为真(或等价于1),但只有一些随机样本为真(或1)。
发布于 2019-02-19 10:18:37
我的方法是创建一个等于1的所有单元格的大列表,然后每行只采样一个单元格,并更新矩阵的副本。如下所示:
idx <- which(dataset==1, arr.ind=TRUE)
idx <- idx[sample(nrow(idx)),]
idx <- idx[!duplicated(idx[,"row"]),]
mat <- matrix(FALSE, nrow=nrow(dataset), ncol=ncol(dataset))
mat[idx] <- TRUE
mat
# [,1] [,2] [,3] [,4] [,5]
#[1,] FALSE TRUE FALSE FALSE FALSE
#[2,] TRUE FALSE FALSE FALSE FALSE
#[3,] FALSE FALSE FALSE TRUE FALSE
#[4,] FALSE FALSE TRUE FALSE FALSE
#[5,] FALSE FALSE FALSE TRUE FALSE这也会有很好的伸缩性。下面是在大约2.5秒内处理的500万行数据:
dataset <- dataset[rep(1:5,1e6),]
system.time({
idx <- which(dataset==1, arr.ind=TRUE)
idx <- idx[sample(nrow(idx)),]
idx <- idx[!duplicated(idx[,"row"]),]
mat <- matrix(FALSE, nrow=nrow(dataset), ncol=ncol(dataset))
mat[idx] <- TRUE
})
# user system elapsed
# 2.32 0.22 2.58 https://stackoverflow.com/questions/54757602
复制相似问题