R: Applying a function to all pairs of matrix rows without a loop

I want all pairwise comparisons for all rows in the matrix, obviously doubles for the loop to work, but extremely expensive for a large dataset.

I was looking for an implicit loop, such apply()as etc., but don't know how to avoid the inner loop.

How can this be achieved?

+5
source share
4 answers

, - . outer() . . :

m <- matrix(1:12,4,3)     
> outer(1:4,1:4, FUN = Vectorize( function(i,j) sum((m[i,]-m[j,])^2 )) )
     [,1] [,2] [,3] [,4]
[1,]    0    3   12   27
[2,]    3    0    3   12
[3,]   12    3    0    3
[4,]   27   12    3    0
+6

outer() , - , 1-1 2-2 .. ( ). , external() 1-2, 2-1 .

, . combn().

, outer() combn()

> v <- c(1,2,3,4)
> outer(v, v, function(x, y) print(paste(x, "-", y)))
 [1] "1 - 1" "2 - 1" "3 - 1" "4 - 1" "1 - 2" "2 - 2" "3 - 2" "4 - 2" "1 - 3" "2 - 3" "3 - 3" "4 - 3" "1 - 4" "2 - 4" "3 - 4" "4 - 4"

"1-1" . "1-2" "2-1". :

> v <- c(1,2,3,4)
> allPairs <- combn(length(v), 2) # choose a pair from 1:length(v)
> a_ply(combn(length(v), 2), 2, function(x) print(paste(x[1],"--",x[2]))) # iterate over all pairs
[1] "1 -- 2"
[1] "1 -- 3"
[1] "1 -- 4"
[1] "2 -- 3"
[1] "2 -- 4"
[1] "3 -- 4" 

" " .

Outer() , . combn.

, outer(x,x,...), , , - combn(length(x),2))

+5

, , @Prasad, :

dist(m)^2
0

@Gopalkrishna Palem

I like your decision! However, I think you should use combn (v, 2) instead of combn (length (v), 2). combn (length (v), 2) iterate over indices v only

> v <- c(3,4,6,7)
> combn(v, 2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    3    3    3    4    4    6
[2,]    4    6    7    6    7    7

> combn(length(v), 2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    1    2    2    3
[2,]    2    3    4    3    4    4

> a_ply(combn(v, 2), 2, function(x) print(paste(x[1],"--",x[2])) )
[1] "3 -- 4"
[1] "3 -- 6"
[1] "3 -- 7"
[1] "4 -- 6"
[1] "4 -- 7"
[1] "6 -- 7"
> a_ply(combn(length(v), 2), 2, function(x) print(paste(x[1],"--",x[2])) )
[1] "1 -- 2"
[1] "1 -- 3"
[1] "1 -- 4"
[1] "2 -- 3"
[1] "2 -- 4"
[1] "3 -- 4"

so the end result is true with combn (v, 2).

Then, if we have a data frame, we can use indexes to apply the function to pairwise strings:

> df
  x  y
1 4  8
2 5  9
3 6 10
4 7 11

a_ply(combn(nrow(df), 2), 2, function(x) print(df[x[1],] - df[x[2],]))
   x  y
1 -1 -1
   x  y
1 -2 -2
   x  y
1 -3 -3
   x  y
2 -1 -1
   x  y
2 -2 -2
   x  y
3 -1 -1

However, a_ply will cancel the result, so how can I save the output in a vector for further analysis? I don't want to just print the result

0
source

All Articles