[R] Converting nested "for" loops to an "apply" function(s)

Dan Davison davison at stats.ox.ac.uk
Sun Aug 10 13:08:42 CEST 2008


On Sat, Aug 09, 2008 at 08:53:00PM -0400, Kurt Newman wrote:
> 
> Resending.  Previous message was truncated.  Sorry for possible confusion.
> 
> ----------------------------------------
> > From: km_newman at hotmail.com
> > To: r-help at r-project.org
> > Date: Sat, 9 Aug 2008 18:25:47 -0400
> > Subject: [R] Converting nested "for" loops to an "apply" function(s)
> > 
> > 
> > Hello,
> > 

> > I would like to know more about how to use the "apply" family and
> > have attempted to convert nested "for" loops in example code from
> > Contributed Documentation ("The Friendly Beginners' R Course? by
> > Toby Marthews (ZIP, 2007-03-01)") to an "apply" function(s).  The
> > relevant code is:

> > 
> > distances=c(51,65,175,196,197,125,10,56)	#distances of 8 houses from the town centre in m
> > bearings=c(10,8,210,25,74,128,235,335)	#bearings of the houses in degrees
> > 
> > xpos=distances*sin(bearings*pi/180)		#in sin and cos the argument MUST be in radians
> > ypos=distances*cos(bearings*pi/180)		
> > 
> > numpoints=length(distances)
> > nnd=rep(sqrt(2*400*400),times=numpoints)	#start with the maximum possible distance
> > for (i in 1:numpoints) {	
> >  for (j in 1:numpoints) {
> >   if (i!=j) {		
> >    diffx=abs(xpos[i]-xpos[j])
> >    diffy=abs(ypos[i]-ypos[j])
> >    nd=sqrt((diffx^2)+(diffy^2))
> >    if (nd < nnd[i]) {nnd[i]=nd}
>   }
>  }
> }
> print(data.frame(xpos,ypos,nnd))
> 

> My attempts to convert the nested "for" loops to an "apply"
>  function(s) have not been successful.  I would like to know how to
>  convert the code to increase my knowledge of R programming and to
>  evaluate operational efficiency of the different strategies.

Hi Kurt,

It's not just the apply() family that help in vectorising problems. In
this case, outer() is also going to be helpful, as well as remembering
that all the standard arithmetical operators automatically
vectorise. I would use something like this:

nearest.neighbour.distance <- function(xpos, ypos) {
    xdist <- abs(outer(xpos, xpos, "-"))
    ydist <- abs(outer(ypos, ypos, "-"))
    dist <- sqrt(xdist^2 + ydist^2)
    diag(dist) <- NA
    apply(dist, 1, min, na.rm=TRUE)
}

Dan


> 
> Thank you in advance for your comments / suggestions.
> 
> Kurt Newman
> 
> 
> 
> > ______________________________________________
> > 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.
> 
> ______________________________________________
> 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