Hi, I have spent some time locating a quite subtle (at least in my opinion) bug in my code. I want two nested for loops traversing the above-diagonal part of a square matrix. In pseudo code it would something like for i = 1 to 10 { for j = i+1 to 10 { // do something } } However, trying to do the same in R, my first try was for (i in 1:10) { for (j in (i+1):10) { // do something } } but there's a problem here. For i=10, the last for loop is over 11:10. Usually programming laguages would regard what corresponds to 11:10 as empty, but A:B with A bigger than B is in R interpreted as the numbers from B to A in reverse order. Is there a clever way to make nested loops like the one above in R? -- Michael Knudsen micknudsen at gmail.com http://lifeofknudsen.blogspot.com/
> -----Original Message----- > From: r-help-bounces at r-project.org > [mailto:r-help-bounces at r-project.org] On Behalf Of Michael Knudsen > Sent: Monday, July 13, 2009 10:39 PM > To: r-help at r-project.org > Subject: [R] Nested for loops > > Hi, > > I have spent some time locating a quite subtle (at least in my > opinion) bug in my code. I want two nested for loops traversing the > above-diagonal part of a square matrix. In pseudo code it would > something like > > for i = 1 to 10 > { > for j = i+1 to 10 > { > // do something > } > } > > However, trying to do the same in R, my first try was > > for (i in 1:10) > { > for (j in (i+1):10) > { > // do something > } > } > > but there's a problem here. For i=10, the last for loop is over 11:10. > Usually programming laguages would regard what corresponds to 11:10 as > empty, but A:B with A bigger than B is in R interpreted as the numbers > from B to A in reverse order. > > Is there a clever way to make nested loops like the one above in R? >Michael, If you are tryuly interested in the ABOVE diagonal elements (i.e. not including diagonal element temselves), the your loop should be for (i in 1:9) { for (j in (i+1):10) { // do something } } And you avoid your current problem. Hope this is helpful, Dan Daniel Nordlund Bothell, WA USA
Make it for (i in 1:9) This is not the general solution, but in your case when i=10 you do not want to do anything. --- On Tue, 14/7/09, Michael Knudsen <micknudsen at gmail.com> wrote:> From: Michael Knudsen <micknudsen at gmail.com> > Subject: [R] Nested for loops > To: r-help at r-project.org > Received: Tuesday, 14 July, 2009, 3:38 PM > Hi, > > I have spent some time locating a quite subtle (at least in > my > opinion) bug in my code. I want two nested for loops > traversing the > above-diagonal part of a square matrix. In pseudo code it > would > something like > > for i = 1 to 10 > { > ???for j = i+1 to 10 > ???{ > ? ? ? // do something > ???} > } > > However, trying to do the same in R, my first try was > > for (i in 1:10) > { > ???for (j in (i+1):10) > ???{ > ? ? ???// do something > ???} > } > > but there's a problem here. For i=10, the last for loop is > over 11:10. > Usually programming laguages would regard what corresponds > to 11:10 as > empty, but A:B with A bigger than B is in R interpreted as > the numbers > from B to A in reverse order. > > Is there a clever way to make nested loops like the one > above in R? > > -- > Michael Knudsen > micknudsen at gmail.com > http://lifeofknudsen.blogspot.com/ > > ______________________________________________ > 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. >
On Jul 14, 2009, at 2:25 AM, Michael Knudsen wrote:> On Tue, Jul 14, 2009 at 8:20 AM, Michael > Knudsen<micknudsen at gmail.com> wrote: > >> What do you mean? It looks a like a very general solution to me. > > Just got an email suggesting using the functions col and row. For > example > > temp = matrix(c(1:36),nrow=6) > which(col(temp)>row(temp))> > This gives the indices (in the matrix viewed as a vector) of the > above-diagonal entries. >If you want the entries it would then be: temp[ col(temp) > row(temp) ] But more simply: > temp[ upper.tri(temp) ] [1] 7 13 14 19 20 21 25 26 27 28 31 32 33 34 35 > If you want the row and column numbers then: > row(temp)[ col(temp) > row(temp)] [1] 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 > col(temp)[ col(temp) > row(temp) ] [1] 2 3 3 4 4 4 5 5 5 5 6 6 6 6 6 Any solution that uses col and row will create two additional matrices of the same size as the original at least for the duration of the operation. For the sub-and super-diagonals: http://finzi.psych.upenn.edu/Rhelp08/2009-March/191379.html -- David Winsemius, MD Heritage Laboratories West Hartford, CT
Try this: seq. <- function(from, to) seq(from = from, length = max(0, to - from + 1)) seq.(11, 10) On Tue, Jul 14, 2009 at 1:38 AM, Michael Knudsen<micknudsen at gmail.com> wrote:> Hi, > > I have spent some time locating a quite subtle (at least in my > opinion) bug in my code. I want two nested for loops traversing the > above-diagonal part of a square matrix. In pseudo code it would > something like > > for i = 1 to 10 > { > ? for j = i+1 to 10 > ? { > ? ? ?// do something > ? } > } > > However, trying to do the same in R, my first try was > > for (i in 1:10) > { > ? for (j in (i+1):10) > ? { > ? ? ? // do something > ? } > } > > but there's a problem here. For i=10, the last for loop is over 11:10. > Usually programming laguages would regard what corresponds to 11:10 as > empty, but A:B with A bigger than B is in R interpreted as the numbers > from B to A in reverse order. > > Is there a clever way to make nested loops like the one above in R? > > -- > Michael Knudsen > micknudsen at gmail.com > http://lifeofknudsen.blogspot.com/ > > ______________________________________________ > 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. >
On Tue, Jul 14, 2009 at 2:29 PM, Gabor Grothendieck<ggrothendieck at gmail.com> wrote:> seq. <- function(from, to) seq(from = from, length = max(0, to - from + 1))Really nice! Thank you! -- Michael Knudsen micknudsen at gmail.com http://lifeofknudsen.blogspot.com/