[R] ugly loop

Marc Schwartz MSchwartz at MedAnalytics.com
Fri Apr 22 15:44:30 CEST 2005


On Fri, 2005-04-22 at 09:31 -0400, Bill Simpson wrote:
> Thanks Marc for your help.
> 
> > > The following code is slow and ugly:
> > > 
> > > count<-0
> > > for(i in 1:nrow(ver))
> > >   for(j in 1:ncol(ver))
> > >     {
> > >     count<-count+1
> > >     x[count]<-pt$x[ver[i,j]]
> > >     y[count]<-pt$y[ver[i,j]]
> > >     z[count]<-pt$z[ver[i,j]]
> > >     }
> > > 
> > > Please help me make it better.
> > > 
> > > Thanks!
> > 
> > The following should work:
> > 
> > > ver <- matrix(sample(1:16, 16), ncol = 4)
> > > pt <- data.frame(x = sample(1:16, 16), 
> > +                  y = sample(1:16, 16),
> > +                  z = sample(1:16, 16))
> >  
> > > ver
> >      [,1] [,2] [,3] [,4]
> > [1,]    8    9    5   13
> > [2,]   14   16    1   10
> > [3,]   12    2   11    7
> > [4,]    6    3    4   15
> > > pt
> >     x  y  z
> > 1   6 15 15
> > 2   9  2  3
> > 3  11  1  5
> > 4  14  4 10
> > 5  13  7 14
> > 6   1 14  7
> > 7  15 10  4
> > 8  10  5 12
> > 9   4 12  2
> > 10  8  8 13
> > 11 16 11  1
> > 12  7 13  9
> > 13  2 16 11
> > 14  3  9 16
> > 15  5  6  8
> > 16 12  3  6
> > 
> > > x <- pt$x[ver]
> > > y <- pt$y[ver]
> > > z <- pt$z[ver]
> This doesn't give the same results as my original code -- it scrambles the 
> order.
> 
> OK I will explain my example.
> 
> pts contains the x, y, z coordinates of some 3D points. These points are 
> the vertices of 3D triangles.
> 
> ver contains the indexes into pts.
> 
> each line of ver contains 3 vertices -- they are the corners of a 
> triangle. For example, if line 1 of ver is
> 10 9 7
> That means I need to draw a triangle whose coordinates are
> pt$x[10],pt$y[10],pt$z[10]
> pt$x[9],pt$y[9],pt$z[9]
> pt$x[7],pt$y[7],pt$z[7]
> 
> Now it should be clear why the ordering is critical.
> I am using rgl.triangles() to plot. It requires the x,y,z coordinates in 
> the order I gave in my original code.

That's what I get for not comparing your results against my own.  I just
noted that you are going by row and not by column. So, using the same
data above:

> count<-0
> for(i in 1:nrow(ver))
+   for(j in 1:ncol(ver))
+     {
+     count<-count+1
+     x[count]<-pt$x[ver[i,j]]
+     y[count]<-pt$y[ver[i,j]]
+     z[count]<-pt$z[ver[i,j]]
+     }
> x
 [1] 10  4 13  2  3 12  6  8  7  9 16 15  1 11 14  5
> y
 [1]  5 12  7 16  9  3 15  8 13  2 11 10 14  1  4  6
> z
 [1] 12  2 14 11 16  6 15 13  9  3  1  4  7  5 10  8


Thus, I just need to use t(ver) instead of ver:

> x <- pt$x[t(ver)]
> y <- pt$y[t(ver)]
> z <- pt$z[t(ver)]
 
> x
 [1] 10  4 13  2  3 12  6  8  7  9 16 15  1 11 14  5
> y
 [1]  5 12  7 16  9  3 15  8 13  2 11 10 14  1  4  6
> z
 [1] 12  2 14 11 16  6 15 13  9  3  1  4  7  5 10  8

That should do it?

HTH,

Marc
<Off to make another pot of coffee....>




More information about the R-help mailing list