[R] Two matrix loop

Thomas Levine thomas.levine at gmail.com
Sun Mar 27 00:12:12 CET 2011


This way uses a three-dimensional array instead of the nested apply.
It seems to take the same amount of time, even on larger datasets, but
it may give you ideas.

distance=function(x) daisy(x, metric = 'gower')

persons=array(dim=c(2,nrow(donor)*nrow(receiver),ncol(receiver)))
persons[1,,]=donor[rep(1:nrow(donor),each=nrow(receiver)),]
persons[2,,]=receiver[rep(1:nrow(receiver),nrow(donor)),]

matrix(apply(persons,2,distance),,nrow(donor))

Tom

On Thu, Mar 24, 2011 at 8:23 AM, Stefan Petersson
<stefan.petersson at inizio.se> wrote:
>
> Hi,
>
> I'm trying to create a distance matrix. And it works out somewhat ok. However, I suspect that there are
> some efficiency issues with my efforts. Plz have a look at this:
>
> donor <- matrix(c(3,1,2,3,3,1,4,3,5,1,3,2), ncol=4)
> receiver <-
> matrix(c(1,4,3,2,4,3,1,5,1,3,2,1,4,5,3,5,1,3,2,4,5,1,2,3,1,4,5,5,1,2,1,3,4,3,2,5,5,1,4,2,5,4,3,2), ncol=4)
>
> The above creates my two matrices. I have three donors, and eleven receivers (rows), with four
> measures (columns) in each matrix.
>
> And now, I want to apply the daisy() function from the cluster library, to calculate distances between my
> three donors, and eleven receivers. The end result should be a 11x3 matrix with distances between the
> units from the two matrices. I can calculate one distance measure (ie donor 1 and receiver 1). Like this:
>
> library(cluster)
> daisy(rbind(donor[1,], receiver[1,]), metric = 'gower')
>
> My first attempt was a simple nested for-loop. But that one was discarded after reading up on efficiency
> issues with for-looping. So I turned to 'apply' with this result:
>
> apply(donor, 1, function(b) apply(receiver, 1, function(a) daisy(rbind(b, a), metric = 'gower')))
>
>      [,1] [,2] [,3]
>  [1,] 1.00 0.50 0.75
>  [2,] 1.00 0.75 0.75
>  [3,] 0.75 1.00 1.00
>  [4,] 0.50 0.75 0.75
>  [5,] 0.75 1.00 0.75
>  [6,] 0.75 1.00 0.50
>  [7,] 0.75 0.50 0.75
>  [8,] 1.00 1.00 1.00
>  [9,] 1.00 0.75 1.00
> [10,] 0.75 0.50 1.00
> [11,] 0.75 1.00 0.25
>
> However, something tells me that there is a simpler (more efficient) way of doing this. I've been reading
> up on the Matrix library, but I'm having trouble understanding the functions...
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list