Dear R users,I come to you with a quite silly question I think, but I hope you can answer me... That is, I've got some problems in using the if and while conditions in a loop. Substantially, I want to select rows in a dataset depending on an index variable (suppose it ranges from 1 to 5), so to make a specific analysis (homemade of course) on thie new dataset. Mi first tought has been to do a double loop like this: for i in 1:5{ for j in (i+1):5{ data = dataset[(variable==i) | (variable==j),] ##analysis ##analysis } } This way I should select all the couples only once (gaining in efficiency I hope). The fact is that this arrangement has a problem: that j ends up with ranging from 2 to 6, not from to 2 to 5. So when I do a subsetting on the dataset to obtain only the rows corresponding to the values of i and j I want, when the loop comes to j = 6 I have an error, of course. What I want to know is: how can I use the if or while condition in such a loop to avoid the routine doing the computations for this case? I.e., can I tell somehow R "Hey, if j=6, let it go and move on with the other computations"? Or maybe you can see a faster and better way of using the for conditions?? I hope I made myself clear, if not I'll carify myself!! Thanks in advance Niccolò [[alternative HTML version deleted]]
On 1/13/2009 8:20 AM, Niccol? Bassani wrote:> Dear R users,I come to you with a quite silly question I think, but I hope > you can answer me... > That is, I've got some problems in using the if and while conditions in a > loop. > Substantially, I want to select rows in a dataset depending on an index > variable (suppose it ranges from 1 to 5), so to make a specific analysis > (homemade of course) on thie new dataset. Mi first tought has been to do a > double loop like this: > > for i in 1:5{ > for j in (i+1):5{ > data = dataset[(variable==i) | (variable==j),] > ##analysis > ##analysis > } > } > > This way I should select all the couples only once (gaining in efficiency I > hope). The fact is that this arrangement has a problem: that j ends up with > ranging from 2 to 6, not from to 2 to 5. So when I do a subsetting on the > dataset to obtain only the rows corresponding to the values of i and j I > want, when the loop comes to j = 6 I have an error, of course. > What I want to know is: how can I use the if or while condition in such a > loop to avoid the routine doing the computations for this case? I.e., can I > tell somehow R "Hey, if j=6, let it go and move on with the other > computations"? > Or maybe you can see a faster and better way of using the for conditions??Use "for (i in 1:4)". Duncan Murdoch> > I hope I made myself clear, if not I'll carify myself!! > > Thanks in advance > Niccol? > > [[alternative HTML version deleted]] > > > > ------------------------------------------------------------------------ > > ______________________________________________ > 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.
Shouldn't your loop be: for (i in 1:4){ for (j in (i+1):5{ ... } } On Tue, Jan 13, 2009 at 8:20 AM, Niccol? Bassani <biostatistica at gmail.com> wrote:> Dear R users,I come to you with a quite silly question I think, but I hope > you can answer me... > That is, I've got some problems in using the if and while conditions in a > loop. > Substantially, I want to select rows in a dataset depending on an index > variable (suppose it ranges from 1 to 5), so to make a specific analysis > (homemade of course) on thie new dataset. Mi first tought has been to do a > double loop like this: > > for i in 1:5{ > for j in (i+1):5{ > data = dataset[(variable==i) | (variable==j),] > ##analysis > ##analysis > } > } > > This way I should select all the couples only once (gaining in efficiency I > hope). The fact is that this arrangement has a problem: that j ends up with > ranging from 2 to 6, not from to 2 to 5. So when I do a subsetting on the > dataset to obtain only the rows corresponding to the values of i and j I > want, when the loop comes to j = 6 I have an error, of course. > What I want to know is: how can I use the if or while condition in such a > loop to avoid the routine doing the computations for this case? I.e., can I > tell somehow R "Hey, if j=6, let it go and move on with the other > computations"? > Or maybe you can see a faster and better way of using the for conditions?? > > I hope I made myself clear, if not I'll carify myself!! > > Thanks in advance > Niccol? > > [[alternative HTML version deleted]] > > > ______________________________________________ > 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. > >-- Jim Holtman Cincinnati, OH +1 513 646 9390 What is the problem that you are trying to solve?
Generally extraction of subsets is better done by subset(). myDat <- subset(dataset, subset= (variable==i) | (variable==j) ) #, or myDat <- dataset[which( (dataset$variable==i) | (dataset $variable==j) ), ] #note the need to add the name of the dataframe in the second version. Both of these avoid the difficult to debug problem that might arise from the sometimes incomplete evaluation of logical expressions. See the example from this morning: --------- z <- data.frame( x = c(5,6,5,NA,7,5,4,NA), y = c(1,2,2,2,2,2,2,2) ) p <- (z$x <= 5) & (z$y == 1) p z[p, "p1"] <-5 z # ok, this works fine (no NA's) I suppose b/c (z$x <= 5) only gets evaluated once z <- z[,-3] p <- (z$x <= 5) & (z$y == 2) # creates NA p z[p, "p2"] <-5 #throws an error due to the NA's z # this failed -------------- The two versions of p above give different results using simple extraction, but the subset function deals with the two conditions in what seems to be a sensible manner. Then, of course, there is the standard warning: avoid naming objects "data". You might gain efficiency by selecting once, and then not repeating the calls to "analysis" I * J times. As I understand the R efficiency strategies, one generally tries to avoid unnecessary repetition of "setting up". -- David Winsemius On Jan 13, 2009, at 8:20 AM, Niccol? Bassani wrote:> Dear R users,I come to you with a quite silly question I think, but > I hope > you can answer me... > That is, I've got some problems in using the if and while conditions > in a > loop.Sorry,did not see that you used "if" or "while" in the example.> > Substantially, I want to select rows in a dataset depending on an > index > variable (suppose it ranges from 1 to 5), so to make a specific > analysis > (homemade of course) on thie new dataset. Mi first tought has been > to do a > double loop like this: > > for i in 1:5{ > for j in (i+1):5{ > data = dataset[(variable==i) | (variable==j),]That effort at extraction might fail. If "variable" is a column within dataset, it is not a full-fledged object. -- David Winsemius> > ##analysis > ##analysis > } > } > > This way I should select all the couples only once (gaining in > efficiency I > hope). The fact is that this arrangement has a problem: that j ends > up with > ranging from 2 to 6, not from to 2 to 5. So when I do a subsetting > on the > dataset to obtain only the rows corresponding to the values of i and > j I > want, when the loop comes to j = 6 I have an error, of course. > What I want to know is: how can I use the if or while condition in > such a > loop to avoid the routine doing the computations for this case? > I.e., can I > tell somehow R "Hey, if j=6, let it go and move on with the other > computations"? > Or maybe you can see a faster and better way of using the for > conditions?? > > I hope I made myself clear, if not I'll carify myself!! > > Thanks in advance > Niccol? > > [[alternative HTML version deleted]] > > ______________________________________________ > 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 13-Jan-09 13:20:54, Niccol? Bassani wrote:> Dear R users,I come to you with a quite silly question I think, > but I hope you can answer me... > That is, I've got some problems in using the if and while conditions > in a loop. > Substantially, I want to select rows in a dataset depending on an > index variable (suppose it ranges from 1 to 5), so to make a specific > analysis (homemade of course) on thie new dataset. Mi first tought > has been to do a double loop like this: > > for i in 1:5{ > for j in (i+1):5{ > data = dataset[(variable==i) | (variable==j),] >##analysis >##analysis > } > } > > This way I should select all the couples only once (gaining in > efficiency I hope). The fact is that this arrangement has a problem: > that j ends up with ranging from 2 to 6, not from to 2 to 5. So when > I do a subsetting on the dataset to obtain only the rows corresponding > to the values of i and j I want, when the loop comes to j = 6 I have > an error, of course. > What I want to know is: how can I use the if or while condition in such > a loop to avoid the routine doing the computations for this case? > I.e., can I tell somehow R "Hey, if j=6, let it go and move on with > the other computations"? > Or maybe you can see a faster and better way of using the for > conditions?? > > I hope I made myself clear, if not I'll carify myself!! > > Thanks in advance > Niccol?Presumably the foloowing summarises the situation you want to avoid: for(i in (1:5)){for(j in ((i+1):5)){ print(c(i,j))}} # [1] 1 2 # [1] 1 3 # [1] 1 4 # [1] 1 5 # [1] 2 3 # [1] 2 4 # [1] 2 5 # [1] 3 4 # [1] 3 5 # [1] 4 5 # [1] 5 6 # [1] 5 5 I.e. you get (5,6) when case 6 is not wanted. If (as seems likely) you don't want (5,5) either (i.e. you only want all pairs (i,j) from 1:5 with i<j), then the following does it: for(i in (1:4)){for(j in ((i+1):5)){ print(c(i,j))}} # [1] 1 2 # [1] 1 3 # [1] 1 4 # [1] 1 5 # [1] 2 3 # [1] 2 4 # [1] 2 5 # [1] 3 4 # [1] 3 5 # [1] 4 5 However, if for some reason you do want (5,5) as well, then: for(i in (1:5)){for(j in (min(5,(i+1)):5)){ print(c(i,j))}} # [1] 1 2 # [1] 1 3 # [1] 1 4 # [1] 1 5 # [1] 2 3 # [1] 2 4 # [1] 2 5 # [1] 3 4 # [1] 3 5 # [1] 4 5 # [1] 5 5 Also (though I suspect it was simply due to hasty typing), the syntax of what you wrote above: for i in 1:5{ for j in (i+1):5{ ... } } will not work, since you must write "for( ... )" and not "for ... ": for i in (1:5) # Error: unexpected symbol in "for i" Hoping this helps, Ted. -------------------------------------------------------------------- E-Mail: (Ted Harding) <Ted.Harding at manchester.ac.uk> Fax-to-email: +44 (0)870 094 0861 Date: 13-Jan-09 Time: 15:09:58 ------------------------------ XFMail ------------------------------
If efficiency is not of concern then this is easy to understand: for(i in 1:5) for(j in 1:5) if (i < j) { ... } On Tue, Jan 13, 2009 at 8:20 AM, Niccol? Bassani <biostatistica at gmail.com> wrote:> Dear R users,I come to you with a quite silly question I think, but I hope > you can answer me... > That is, I've got some problems in using the if and while conditions in a > loop. > Substantially, I want to select rows in a dataset depending on an index > variable (suppose it ranges from 1 to 5), so to make a specific analysis > (homemade of course) on thie new dataset. Mi first tought has been to do a > double loop like this: > > for i in 1:5{ > for j in (i+1):5{ > data = dataset[(variable==i) | (variable==j),] > ##analysis > ##analysis > } > } > > This way I should select all the couples only once (gaining in efficiency I > hope). The fact is that this arrangement has a problem: that j ends up with > ranging from 2 to 6, not from to 2 to 5. So when I do a subsetting on the > dataset to obtain only the rows corresponding to the values of i and j I > want, when the loop comes to j = 6 I have an error, of course. > What I want to know is: how can I use the if or while condition in such a > loop to avoid the routine doing the computations for this case? I.e., can I > tell somehow R "Hey, if j=6, let it go and move on with the other > computations"? > Or maybe you can see a faster and better way of using the for conditions?? > > I hope I made myself clear, if not I'll carify myself!! > > Thanks in advance > Niccol? > > [[alternative HTML version deleted]] > > > ______________________________________________ > 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. > >