如果元素不为零,请添加匹配的行值

时间:2016-08-17 22:08:34

标签: r loops if-statement conditional

这个打破了我的大脑:

我有一个彼此战斗的个人(A-D)的数据框架(或矩阵,如果需要)。获胜者在矩阵中的列中的行和输家。我需要计算(对于每个获胜者),他们的输家赢得其他战斗的次数:

 | A | B | C | D 
A| 0 | 0 | 1 | 1
B| 1 | 0 | 1 | 0
C| 0 | 0 | 0 | 1
D| 0 | 1 | 1 | 0

所以我想创建变量L(失败者胜利),这样对于每个人,如果他/她击败另一个人,他们的行被加总并加到总数中。在此示例中,新变量如下所示:

 | A | B | C | D | L
A| 0 | 0 | 1 | 1 | 3 (1 win from C, 2 from D)
B| 1 | 0 | 1 | 0 | 3 (2 wins from A, 1 from C)
C| 0 | 0 | 0 | 1 | 2 (2 wins from D)
D| 0 | 1 | 1 | 0 | 3 (2 wins from B, 1 from D)

我已经尝试了 for 循环,并设法使用以下内容获取每个人的rowSums:

l=c()
for (i in 1:nrow(df)){
l[i]=rowSums(df[i,])
}
loserwinners=data.frame(l,row.names=rownames(df))

我知道,金星,哇。但是,如果值非零,我不知道在矩阵内调用的逻辑语句,将该列名称与行名称匹配,并将该行的值添加到总计中。我很感激有关如何做到这一点的任何线索,并在语法错误时道歉!

1 个答案:

答案 0 :(得分:3)

我认为这样的事情应该有效。使用applyMARGIN = 1循环行。在每一行中,标识大于0的列,并存储名称。然后将与每个列名对应的行的所有值相加。

fights <- matrix(c(0L, 0L, 1L, 1L, 
                   1L, 0L, 1L, 0L, 
                   0L, 0L, 0L, 1L, 
                   0L, 1L, 1L, 0L), 
                 nrow = 4, byrow = TRUE)
rownames(fights) <- colnames(fights) <- LETTERS[1:4]

L <- apply(fights, 1, function(x) {
  who_lost <- names(which(x > 0))
  sum(fights[who_lost, ])
})

cbind(fights, L)

##   A B C D L
## A 0 0 1 1 3
## B 1 0 1 0 3
## C 0 0 0 1 2
## D 0 1 1 0 3

修改:要展开我在下方的评论,如果您的行和列位于 同样的订单names(which())是多余的:

L <- apply(fights, 1, function(x) {
  who_lost <- x > 0
  sum(fights[who_lost, ])
})

cbind(fights, L)

##   A B C D L
## A 0 0 1 1 3
## B 1 0 1 0 3
## C 0 0 0 1 2
## D 0 1 1 0 3