On 11/10/2006 12:52 PM, Romain Francois wrote: > Duncan Murdoch wrote: >> On 11/9/2006 5:14 AM, Romain Francois wrote: >>> Hello, >>> >>> What about an `invert` argument in grep, to return elements that are >>> *not* matching a regular expression : >>> >>> R> grep("pink", colors(), invert = TRUE, value = TRUE) >>> >>> would essentially return the same as : >>> >>> R> colors() [ - grep("pink", colors()) ] >>> >>> >>> I'm attaching the files that I modified (against today's tarball) for >>> that purpose. >> >> I think a more generally useful change would be to be able to return a >> logical vector with TRUE for a match and FALSE for a non-match, so a >> simple !grep(...) does the inversion. (This is motivated by the >> recent R-help discussion of the fact that x[-selection] doesn't always >> invert the selection when it's a vector of indices.) >> >> A way to do that without expanding the argument list would be to allow >> >> value="logical" >> >> as well as value=TRUE and value=FALSE. >> >> This would make boolean operations easy, e.g. >> >> colors()[grep("dark", colors(), value="logical") >> & !grep("blue", colors(), value="logical")] >> >> to select the colors that contain "dark" but not "blue". (In this case >> the RE to select that subset is rather simple because "dark" always >> precedes "blue", but if that wasn't true, it would be a lot messier.) >> >> Duncan Murdoch > Hi, > > It sounds like a nice thing to have. I would still prefer to type : > > R> grep ( "dark", grep("blue", colors(), value = TRUE, invert=TRUE), > value = TRUE )
That's good for intersecting two searches, but not for other boolean combinations. My main point was that inversion isn't the only boolean operation you may want, but R has perfectly good powerful boolean operators, so installing a limited subset of boolean algebra into grep() is probably the wrong approach. > > > What about a way to pass more than one regular expression then be able > to call : > > R> grep( c("dark", "blue"), colors(), value = TRUE, invert = c(TRUE, FALSE) Again, it covers & and !, but it misses other boolean operators. > I usually use that kind of shortcuts that are easy to remember. > > vgrep <- function(...) grep(..., value = TRUE) > igrep <- function(...) grep(..., invert = TRUE) > ivgrep <- vigrep <- function(...) grep(..., invert = TRUE, value = TRUE) If you're willing to write these, then it's easy to write igrep without an invert arg to grep: igrep <- function(pat, x, ...) setdiff(1:length(x), grep(pat, x, value = FALSE, ...)) ivgrep would also be easy, except for the weird semantics of value=TRUE pointed out by Brian: but it could still be written with a little bit of care. Duncan Murdoch > > What about things like the arguments `after` and `before` in unix grep. > That could be used when grepping inside a function : > > R> grep("plot\\.", body(plot.default) , value= TRUE) > [1] "localWindow <- function(..., col, bg, pch, cex, lty, lwd) > plot.window(...)" > [2] "plot.new()" > [3] "plot.xy(xy, type, ...)" > > > when this could be useful (possibly). > > R> # grep("plot\\.", plot.default, after = 2, value = TRUE) > R> tmp <- tempfile(); sink(tmp) ; print(body(plot.default)); sink(); > system( paste( "grep -A2 plot\\. ", tmp) ) > localWindow <- function(..., col, bg, pch, cex, lty, lwd) > plot.window(...) > localTitle <- function(..., col, bg, pch, cex, lty, lwd) title(...) > xlabel <- if (!missing(x)) > -- > plot.new() > localWindow(xlim, ylim, log, asp, ...) > panel.first > plot.xy(xy, type, ...) > panel.last > if (axes) { > -- > if (frame.plot) > localBox(...) > if (ann) > > > BTW, if I call : > > R> grep("plot\\.", plot.default) > Error in as.character(x) : cannot coerce to vector > > What about adding that line at the beginning of grep, or something else > to be able to do as.character on a function ? > > if(is.function(x)) x <- body(x) > > > Cheers, > > Romain >>> >>> Cheers, >>> >>> Romain > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel