根据二项式测试将频率矩阵转换为r中的二进制矩阵

时间:2014-03-29 04:18:21

标签: r matrix

我有一个矩阵,例如这个例子,其中a1,a2,a3,a4和a5指的是彼此竞争的个人。矩阵的行代表对列中相同个体的“胜利”。

所以在下面的例子中,个人a2击败a4 12次,而a4击败a2 13次,这意味着他们共有25场比赛。

在这个例子中,对角线都是0,但它们很容易成为NA,因为每个人都不可能与自己竞争。

底层使您可以创建数据框/矩阵:

a1<-c(0,13,3,33,0)
a2<-c(1,0,22,13,1)
a3<-c(1,0,0,2,2)
a4<-c(1,12,22,0,12)
a5<-c(3,1,0,0,0)
df<-as.data.frame(cbind(a1,a2,a3,a4,a5))
rownames(df)<-c("a1","a2","a3","a4","a5")
df
m<-as.matrix(df)
m

矩阵看起来像这样:

   a1 a2 a3 a4 a5
a1  0  1  1  1  3
a2 13  0  0 12  1
a3  3 22  0 22  0
a4 33 13  2  0  0
a5  0  1  2 12  0

我想要做的是将此频率矩阵转换为二进制矩阵。我希望根据针对p = 0.5的二项式测试测试,如果他们在特定列中具有比偶然预期更多的胜利,那么我想在每个人的行中输入一个1。

因此,对于a2对a4,你可以像这样运行binom.test

binom.test(c(12,25), 0.5))

表示这并不重要。因此,在行a2,a4列的单元格中,我们将输入0.我们还在a4行a2中输入0。

然而,a4在34次中击败a1 33次,而a1在34次击败a4次。为此运行二项式测试:

binom.test(c(33,34), 0.5))

这显然很重要,因此第a4列a1应该得到'1',但是a1列a4得到'0'。

结果矩阵应如下所示:

   a1 a2 a3 a4 a5
a1  0  0  0  0  0
a2  1  0  0  0  0
a3  0  1  0  1  0
a4  1  0  0  0  0
a5  0  0  0  1  0

我一直在尝试一些方法,但到目前为止都失败了。

任何赞赏和欢迎的想法。

1 个答案:

答案 0 :(得分:0)

我承认,我本来打算骂你“做错了”,然后我 重新阅读页面以及您如何进行操作并重新学习 binom.test。你的问题中有一个问题就在于你 错过逗号,但我猜这只是一个打字问题 进入SO。

SIDE POINT:请复制/粘贴工作代码。这需要更多的时间 当描述的代码不均匀时,试图推断出你的意思 少运行得到所需的输出。

但是,你仍然称错了。来自?binom.test,如果你 将x定义为两个值的向量,那么它必须是“的数量” 成功和失败“,而不是(看起来你已经做过)”数字 成功和试验。“要么:

binom.test(12, 12+13, 0.5)

binom.test(c(12, 13), 0.5)

其次,这里没有什么能说服你如何尝试 自动化。你说“行a4列a1应该得到'1',但是a1 列a4得到'0'“,但我不知道你曾经得到过什么代码 那里。如果您需要有关您尝试过的代码的帮助,请加入, 即使它不优雅。学习高效优雅的最佳方式 编码实践是将你生成的内容和调整内容进行调整 地方。

一些代码。试试这个:

# define the function
func <- function(mtx, p=0.5, alpha=0.05) {
    # preallocate the matrix in memory
    m2 <- mtx
    for (rr in 2:nrow(mtx)) {
        for (cc in 1:(rr-1)) {
            # these two `for` loops work on the non-diag lower triangle
            x <- mtx[rr,cc]
            y <- mtx[cc,rr]
            sig <- (binom.test(x, x+y, p)$p.value <= alpha)
            # lower-triangle entry
            m2[rr,cc] <- 1*((x>y) & sig)
            # opposing element in the upper-triangle
            m2[cc,rr] <- 1*((y>x) & sig)
        }
    }
    m2
}

# requisite variables
a1 <- c(0,13,3,33,0)
a2 <- c(1,0,22,13,1)
a3 <- c(1,0,0,2,2)
a4 <- c(1,12,22,0,12)
a5 <- c(3,1,0,0,0)

# merge them sequentially into a matrix
m <- matrix(c(a1, a2, a3, a4, a5),
            byrow=FALSE, nrow=5,
            dimnames=list(paste0('a', 1:5), paste0('a', 1:5)))

func(m)
#    a1 a2 a3 a4 a5
# a1  0  0  0  0  0
# a2  1  0  0  0  0
# a3  0  1  0  1  0
# a4  1  0  0  0  0
# a5  0  0  0  1  0

一些注意事项:

  • 尽管如此,通过较低三角形稍微更有效地循环 在1:nrow(m)rrcc执行rr == cc并非错误。你可以 检查代码中的binom.test(如果1*(...)是计算的 例如,昂贵的,但在这个例子中,它不会花费你太多 一点都不但是,如果/当您使用需要更长时间的测试时 计算,你会想要在这里和那里保存一两秒 你的代码。

  • as.integer(...)将布尔值强制转换为0或1.我也可以 完成(x>y)具有相同的效果。

  • binom.test确保“重要”的binom.test(0, 100, 0.5)结果为 仅限获奖者,因为binom.test仍然存在 非常重要(虽然是失败者)。

希望这有帮助。

编辑:删除了m的双重测试,因为(正如@rawr正确指出的那样)它是多余的;并且直接从函数内部而不是内部mtx错误地访问{{1}}变量。