Alex - 1 year ago 110
R Question

# How to apply a function to all combinations of rows in a data frame?

I have trouble solving the following problem concerning the (simplified by limiting number of columns) data frame 'annotations' below.

``````require(irr)
# data
annotations <- read.table(text = "Obj1    Obj2    Obj3
Rater1     a       b       c
Rater2     a       b       b
Rater3     a       b       c", header = TRUE, stringsAsFactors = FALSE)
``````

I would like to apply the function agree from the irr package to all combinations (not permutations) of rows, resulting in the following.

``````Agreement rater 1-2: 67%
Agreement rater 1-3: 100%
Agreement rater 2-3: 67%
``````

I need to run a function on all combinations of rows and the function would need to access a number of/all columns.

I have worked out parts of the answer to the problem; I have generated a list of combinations running
`combn(rownames(annotations), 2)`
, but I don't see how to use this list without writing inefficient for loops.

I have tried apply, as in
`apply(annotations, 1, agree)`
, but I can only get this to work on one row, not the combinations mentioned before.

Does anyone have an idea how to proceed?

UPDATE: The following solution, based on your suggestions, works. (I have used
`kappa2`
from the irr package instead of
`agree`
, but the solution to the main question remains the same.)

``````require(irr) #require the irr library for agreement calculations
annotations <- read.table(text = "Obj1    Obj2    Obj3
Rater1     a       b       c
Rater2     a       b       b
Rater3     a       b       c
Rater4     c       a       a", header = TRUE, stringsAsFactors = FALSE)

annotations <- t(annotations) #transpose annotations (rows become columns and vice versa)
kappa_list <- combn(colnames(annotations), 2, FUN=function(x) kappa_list[[length(kappa_list)+1]] = kappa2(matrix(c(annotations[,x[1]], annotations[,x[2]]), ncol=2))\$value) #fill kappa_list with all pairs of columns (combinations of 2 raters) in annotations and, per combination, add a value to kappa_list that consists of the value of kappa2 applied to the current combination of raters
kappa_list # display the list of values
``````

You are close, you just need to `apply` on the result of `combn` instead. I have no idea what function you are referring to, but this should work the same if you plug in your function.

First, save the results as a list instead, because it is easier to add names (which I am adding my combining the two entries together):

``````toCheck <- combn(rownames(annotations), 2, simplify = FALSE)

names(toCheck) <-
sapply(toCheck, paste, collapse = " - ")
``````

Then, use `sapply` to work through your combinations. Here, I am using `mean` to do the comparison, but use what you need here. If you are returning more than a single value, use `lapply` then work with the result to print as desired

``````sapply(toCheck, function(x){
mean(annotations[x[1], ] == annotations[x[2], ])
})
``````

Which returns:

``````Rater 1 - Rater 2 Rater 1 - Rater 3 Rater 2 - Rater 3
0.6666667         1.0000000         0.6666667
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download