使用矩阵值作为索引

Hei*_*erg 2 r combinatorics

我正在做Fisher的排列测试,其中我必须生成治疗状态的所有组合.

我们有4个科目,其中2个接受治疗.使用combn,我可以生成所有受治疗科目的组合.例如,第一行表示处理第一和第二主题.

t(combn(4, 2))

     [,1] [,2]
[1,]    1    2
[2,]    1    3
[3,]    1    4
[4,]    2    3
[5,]    2    4
[6,]    3    4
Run Code Online (Sandbox Code Playgroud)

如何从此矩阵转到治疗状态矩阵,如下所示:

      [,1] [,2] [,3] [,4]
[1,]    1    1    0   0
[2,]    1    0    1   0
...
Run Code Online (Sandbox Code Playgroud)

Her*_*oka 6

使用base-R:

res <- t(apply(t(combn(4,2)),MARGIN=1,FUN=function(x){
  return(as.numeric(1:4 %in% x))
}))
> res
     [,1] [,2] [,3] [,4]
[1,]    1    1    0    0
[2,]    1    0    1    0
[3,]    1    0    0    1
[4,]    0    1    1    0
[5,]    0    1    0    1
[6,]    0    0    1    1
Run Code Online (Sandbox Code Playgroud)


Mic*_*ico 5

怎么样:

out <- matrix(0L, nrow = nrow(x), ncol = max(x))

for (i in 1:nrow(x)) out[i, x[i, ]] <- 1L

> out
     [,1] [,2] [,3] [,4]
[1,]    1    1    0    0
[2,]    1    0    1    0
[3,]    1    0    0    1
[4,]    0    1    1    0
[5,]    0    1    0    1
[6,]    0    0    1    1
Run Code Online (Sandbox Code Playgroud)

我们也可以在没有循环的情况下执行此操作,但它可能稍微不那么可读(感谢@Frank的步法):

m <- matrix(0L, choose(4, 2), 4)
m[cbind(rep(1:choose(4, 2), each = 2), c(combn(4, 2)))] <- 1L
Run Code Online (Sandbox Code Playgroud)

轻松包装成功能:

participants <- function(m, n){
  if (n > m) stop( )
  mcn <- choose(m, n)
  out <- matrix(0L, mcn, m)
  out[cbind(rep(1:mcn, each = n), c(combn(m, n)))] <- 1L
  out
}

> participants(6, 5)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    1    1    1    0
[2,]    1    1    1    1    0    1
[3,]    1    1    1    0    1    1
[4,]    1    1    0    1    1    1
[5,]    1    0    1    1    1    1
[6,]    0    1    1    1    1    1
Run Code Online (Sandbox Code Playgroud)

  • 您可以使用(1)`choose`来获得组合数和(2)矩阵赋值而不是循环:`m < - 矩阵(0L,选择(4,2),4); m [cbind(rep(1:choose(4,2),each = 2),c(combn(4,2)))] < - 1L`.同样的想法. (2认同)