[R] Relase positive with log and zero of negative with 0

Martin Maechler maechler at stat.math.ethz.ch
Wed Nov 18 09:27:32 CET 2009


>>>>> "PE" == Peter Ehlers <ehlers at ucalgary.ca>
>>>>>     on Mon, 16 Nov 2009 06:55:00 -0700 writes:

    PE> David Winsemius wrote:
    >> 
    >> On Nov 15, 2009, at 10:18 AM, <rkevinburton at charter.net> wrote:
    >> 
    >>> This is a very simple question but I couldn't form a site search 
    >>> quesry that would return a reasonable result set.
    >>> 
    >>> Say I have a vector:
    >>> 
    >>> x <- c(0,2,3,4,5,-1,-2)
    >>> 
    >>> I want to replace all of the values in 'x' with the log of x. 
    >>> Naturally this runs into problems since some of the values are 
    >>> negative or zero. So how can I replace all of the positive elements of 
    >>> x with the log(x) and the rest with zero?
    >> 
    >> > x <- c(0,2,3,4,5,-1,-2)
    >> > x <- ifelse(x>0, log(x), 0)
    >> Warning message:
    >> In log(x) : NaNs produced
    >> > x
    >> [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 0.0000000 0.0000000
    >> 
    >> The warning is harmless as you can see, but if you wanted to avoid it, 
    >> then:
    >> 
    >> > x[x<=0] <- 0; x[x>0] <-log(x[x>0])
    >> 
    >> In the second command, you need to have the logical test on both sides 
    >> to avoid replacement " out of synchrony."
    >> 
    PE> Here is one more way, somewhat less transparent, motivated
    PE> by the examples on the ?ifelse page:


    PE> x <- log(ifelse(x > 0, x, 1))

Yes, indeed.  And this one pretty clearly demonstrates
that -- from an analytic point of view --
this is really in most cases a "non-sense" transformation:
one and all negative numbers are mapped to zero; 
the rest is log transformed:

Look at its graph via

     curve(log(ifelse(x > 0, x, 1)), -2, 3)

Rather  log(abs(x))
or      log(abs(x + eps))  {eps = 1 or eps = 1e-10 or ...}
typically are more useful for what I guess the OP wants the
trafo to use for...
or then, if you think further and want a
  -  monotone
  -  continuous and even smooth (once-differentiable)
log-like transformation 
then consider using the  u.log() function I have written some 13 years ago,
(inspired by coffebreak discussions with Werner Stahel)
available from 

install.packages("sfsmisc")
require("sfsmisc")

curve(u.log, -2, 3, col=2)
curve(u.log(x, c=0.5), add=TRUE, col=3)

?u.log

----

Martin Maechler, ETH Zurich




More information about the R-help mailing list