From rfrancois at mango-solutions.com  Fri Nov 10 18:52:28 2006
From: rfrancois at mango-solutions.com (Romain Francois)
Date: Fri, 10 Nov 2006 17:52:28 +0000
Subject: [Rd] invert argument in grep
In-Reply-To: <45544E94.3090303@stats.uwo.ca>
References: <4552FF83.6010001@mango-solutions.com>
	<45544E94.3090303@stats.uwo.ca>
Message-ID: <4554BC5C.9030203@mango-solutions.com>

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 )  


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)


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)

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


-- 
*mangosolutions*
/data analysis that delivers/

Tel   +44 1249 467 467
Fax   +44 1249 467 468



[Rd] invert argument in grep
Romain Francois