rnso
rnso

Reputation: 24535

how to avoid this double 'for' loop in R

I have to perform function on all combinations of columns of a data frame ddf. I normally do it with:

myfunction <- function(col1, col2) {print(aov(col1~col2))}
ddf = data.frame(first=1:3, second=letters[1:3], third=LETTERS[1:3])

len = length(ddf)
for(i in 1:len) for(j in 1:len) myfunction(ddf[,i], ddf[,j])
[1] "1 1"
[1] "1 a"
[1] "1 A"
[1] "a 1"
[1] "a a"
[1] "a A"
[1] "A 1"
[1] "A a"
[1] "A A"

How can I avoid using 'for' loop in this situation? I tried apply but it takes only one column at a time:

apply(ddf, 2, myfunction)

Thanks for your help.

Upvotes: 2

Views: 1142

Answers (2)

andrewzm
andrewzm

Reputation: 460

agstudy's option is great. Another option is to generate the iteration map beforehand and then use apply on this:

iterate <- expand.grid(1:3,1:3)
X <- apply(iterate,1,function(x) myfunction(ddf[,x[1]],ddf[,x[2]]))

It's probably worth going down this route only if you have a seriously large number of columns and a multi-core system. Then you would parallelise it using one of the parallel apply operations in the parallel package.

Upvotes: 2

agstudy
agstudy

Reputation: 121568

You can use outer with a vectorized version of your function using mapply.

id <- seq_along(colnames(ddf))
outer(id,id,function(x,y)mapply(myfunction,ddf[,x],ddf[,y]))

Upvotes: 2

Related Questions