我有一个矩阵,例如这个例子,其中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
我一直在尝试一些方法,但到目前为止都失败了。
任何赞赏和欢迎的想法。
答案 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)
和rr
上cc
执行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}}变量。