R Ha - 1 year ago 48

R Question

This one is breaking my brain:

I have a data.frame (or matrix if need be) of individuals (A-D) that have fought one another. Winners are on rows and losers in columns in a matrix. I need to calculate (for each winner), how many times their losers won other battles:

`| A | B | C | D`

A| 0 | 0 | 1 | 1

B| 1 | 0 | 1 | 0

C| 0 | 0 | 0 | 1

D| 0 | 1 | 1 | 0

So I would like to create variable L (loser wins) such that for each individual, if he/she beat an another individual, their row is summed and added to a total. In this example, the new variable would look like this:

`| 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)

I have tried a

`l=c()`

for (i in 1:nrow(df)){

l[i]=rowSums(df[i,])

}

loserwinners=data.frame(l,row.names=rownames(df))

I know, gold star, whoopee. But I don't know the logical statement to call within a matrix if a value is non-zero, match that column name to the row name and add that row's values to a total. I would appreciate any leads on how to do this, and apologies if the syntax is incorrect!

Answer Source

Something like this should work I think. Loop across the rows with `apply`

with `MARGIN = 1`

. In each row, identify the columns that are greater than 0, and store the names. Then sum all of the values for the row(s) that correspond to each column name.

```
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]
fights
## 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 <- 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
```