如何生成矩阵A)每行的单个值为1; B)行总和为一

时间:2014-12-26 21:42:08

标签: r matrix

这是一个由两部分组成的问题:第一个是创建一个NXN方阵,每行中只有一个随机元素为1,其他项必须为零。 (即每行中元素的总和为1)。

第二种是创建一个NXN方阵,每行的项目总和为1,但每个元素都遵循一个分布,例如:正态分布。

相关问题包括(Create a matrix with conditional sum in each row -R) Matlab似乎自动完成了我想做的事情(Why this thing happens with random matrix such that all rows sum up to 1?),但我正在寻找r中的解决方案。

以下是我的尝试:

# PART 1

N <- 50
x <- matrix(0,N,N)
lapply(1:N, function(y){
x[y,sample(N,1)]<- 1
})

(我还是零)

# PART 2
N <- 50
x <- matrix(0,N,N)
lapply(1:N, function(y){
x[y,]<- rnorm(N)
})

(需要扩展)

3 个答案:

答案 0 :(得分:2)

这是另一个使用"[<-"函数的两列寻址工具的无环解决方案。这将创建一个双列索引矩阵,其第一列只是一个升序系列,用于指定行位置,第二列(负责选择列位置的列)是一个随机整数值。 (这是马修“最简单的方法”的矢量化版本,我怀疑会更快,因为只有一次调用sample。):

M <- matrix(0,N,N)
M[ cbind(1:N, sample(1:N, N, rep=TRUE))] <- 1

> rowSums(M)
 [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

如果你没有指定rep=TRUE,那么colSums(M)也会一直都是,但那不是你要求的。它确实意味着你得到的矩阵的秩可能小于N.如果你遗漏了rep=TRUE矩阵将是满级。

答案 1 :(得分:1)

在这里,您了解为什么lapply并不总是替换循环。您正在尝试遍历x行并修改矩阵,但您要修改的是来自全局环境的x的副本。

最简单的解决方法是使用for循环:

for (y in 1:N) {
  x[y,sample(N,1)]<- 1
}

apply系列应该用于返回值,而不是带有副作用的编程函数。

执行此操作的方法是返回行,然后将rbind它们返回到矩阵中。这里显示了第二个示例,因为它更像apply

do.call(rbind, lapply((1:N), function(i) rnorm(N)))

然而,这更具可读性:

matrix(rnorm(N*N), N, N)

现在缩放它以使行总和等于1.您使用矩阵是面向列的并且向量被回收的事实,这意味着您可以将矩阵M除以rowSums(M) 。使用更合理的N=5

m <- matrix(rnorm(N*N), N, N)
m/rowSums(m)
##           [,1]       [,2]        [,3]        [,4]        [,5]
## [1,] 0.1788692  0.5398464  0.24980924 -0.01282655  0.04430168
## [2,] 0.4176512  0.2564463  0.11553143  0.35432975 -0.14395871
## [3,] 0.3480568  0.7634421 -0.38433940  0.34175983 -0.06891932
## [4,] 1.1807180 -0.0192272  0.16500179 -0.31201400 -0.01447859
## [5,] 1.1601173 -0.1279919 -0.07447043  0.20865963 -0.16631458 

答案 2 :(得分:0)

无循环解决方案:)

n <- 5
# on which column in each row insert 1s
s <- sample(n,n,TRUE)
# indexes for each row
w <- seq(1,n*n,by=n)-1
index <- s+w
# vector of 0s
vec <- integer(n*n)
# put 1s
vec[index] <- 1
# voila :)
matrix(vec,n,byrow = T)
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    0    0    1    0
[3,]    0    0    0    0    1
[4,]    1    0    0    0    0
[5,]    1    0    0    0    0