给出一个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
有人可以帮助我弄清楚如何实现这一目标。
答案 0 :(得分:2)
这是一个选择
# 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
我添加了一个固定的随机种子以提高可重复性;删除以从1
的每一行中随机采样dataset
。
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
答案 1 :(得分:1)
如果我理解了请求,那么这应该是一个有效的答案:
(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相同的位置上找到TRUE(或等价于1),但是只有其中一些随机样本才是TRUE(或1)
答案 2 :(得分:1)
我可以通过列出所有等于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