Greetings, all. I'm fiddling with some text manipulation in R, and I've found something which feels counterintuitive to my PERL-trained senses; I'm hoping that I can glean new R intuition about the situation. Here's an example, as concise as I could make it. trg<-c("this","that") # these two work as I'd expected. if ( grep("this",trg) ) { cat("Y\n") } else { cat("N\n") } if ( grep("that",trg) ) { cat("Y\n") } else { cat("N\n") } # These all fail with error 'argument is of length zero' # if ( grep("other",trg) ) { cat("Y\n") } else { cat("N\n") } # if ( grep("other",trg) == TRUE) { cat("Y\n") } else { cat("N\n") } # if ( grep("other",trg) == 1) { cat("Y\n") } else { cat("N\n") } # This says that the result is a numeric zero. Shouldn't I be able # to "if" on that, or at least compare it with a number? grep("other", trg) # I eventually decided this worked, but felt odd to me. if ( any(grep("other",trg))) { cat("Y\n") } else { cat("N\n") } So, is the 'Wrap it in an any()' just normal R practice, and I'm too new to know it? Is there a more fundamental dumb move I'm making? - Allen S. Rout
If you are using grep then I think you have it right. Note that "this" %in% trg is also available. On 26 Jul 2006 11:16:25 -0400, Allen S. Rout <asr at ufl.edu> wrote:> > > > Greetings, all. > > I'm fiddling with some text manipulation in R, and I've found > something which feels counterintuitive to my PERL-trained senses; I'm > hoping that I can glean new R intuition about the situation. > > Here's an example, as concise as I could make it. > > > trg<-c("this","that") > > # these two work as I'd expected. > if ( grep("this",trg) ) { cat("Y\n") } else { cat("N\n") } > if ( grep("that",trg) ) { cat("Y\n") } else { cat("N\n") } > > # These all fail with error 'argument is of length zero' > # if ( grep("other",trg) ) { cat("Y\n") } else { cat("N\n") } > # if ( grep("other",trg) == TRUE) { cat("Y\n") } else { cat("N\n") } > # if ( grep("other",trg) == 1) { cat("Y\n") } else { cat("N\n") } > > > # This says that the result is a numeric zero. Shouldn't I be able > # to "if" on that, or at least compare it with a number? > grep("other", trg) > > # I eventually decided this worked, but felt odd to me. > if ( any(grep("other",trg))) { cat("Y\n") } else { cat("N\n") } > > > So, is the 'Wrap it in an any()' just normal R practice, and I'm too > new to know it? Is there a more fundamental dumb move I'm making? > > > > > - Allen S. Rout > > ______________________________________________ > R-help at stat.math.ethz.ch 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 Wed, 26 Jul 2006, Allen S. Rout wrote:> # These all fail with error 'argument is of length zero' > # if ( grep("other",trg) ) { cat("Y\n") } else { cat("N\n") } > # if ( grep("other",trg) == TRUE) { cat("Y\n") } else { cat("N\n") } > # if ( grep("other",trg) == 1) { cat("Y\n") } else { cat("N\n") } > > > # This says that the result is a numeric zero. Shouldn't I be able > # to "if" on that, or at least compare it with a number? > grep("other", trg)It is a numeric(0), that is, a zero-length vector of numbers. If you compare it with a number you get a zero-length logical vector. You can't get TRUE or FALSE, because a zero-length vector of 1s looks just like a zero-length vector of 0s, (or a zero-length vector of any other number) In handling zero-length vectors (and in other vectorization contexts) it is useful to distinguish between vectorized functions, which return a vector of the same length as the input, and reducing functions, which return a vector of length 1. The == operator is vectorized, but if() requires a condition of length 1, so they don't match. The solution is to apply some reducing function. Two possible options are length() and (as you found) any(). -thomas Thomas Lumley Assoc. Professor, Biostatistics tlumley at u.washington.edu University of Washington, Seattle