s-news
[Top] [All Lists]

jittering dates - summary of replies

To: s-news@wubios.wustl.edu
Subject: jittering dates - summary of replies
From: Karen_Byron@bd.com
Date: Fri, 13 May 2005 15:54:29 -0400
Original Post
   I have a plot generated with a timeDate x and a continuous y.  I would
   like to jitter x value, but jitter does not work with a timeDate input.
   The problem seems to arise when jitter checks if x is infinite.  Does
   anyone have a jitterDate function?  Thanks for any help.  I will be glad
   to summarize to the list.

   # trivial example
   > timeDate(as.character(1:3))
   [1] 01/01/1960 01:00:00.000 01/01/1960 02:00:00.000 01/01/1960
   03:00:00.000
   > jitter(timeDate(as.character(1:3)))
   Problem in is.number(x) & !is.inf(x): length of longer operand (5)
   should be a multiple of length of shorter (3)
   Use traceback() to see the call stack
   > is.number(timeDate(as.character(1:3)))
   [1] F F F
   > is.inf(timeDate(as.character(1:3)))
   [1] F F F F F
   > is.infinite(timeDate(as.character(1:3)))
   [1] F F F F F

Answer Summary
   I received answers from four people.  All of the replies were useful
   depending on your needs.  Both Sundar's and Sam's worked well for me.

   From Sundar Dorai-Raj
      If all you need to do is jitter for plotting purposes, then the
      following should work:

      set.seed(1)
      # generate data
      n <- 5
      x <- timeDate(as.character(1:n))
      jx <- jitter(as.numeric(x))
      z <- rnorm(n)
      # determine x-limits
      xlim <- range(jx)
      # expand x-limits by 10%
      xlim <- xlim + c(-1, 1) * 0.10 * diff(xlim)
      # set up device
      plot(x, z, type = "n", xlim = xlim)
      # add points
      points(jx, z, pch = 16, col = 2)

   From Matt Austin
      > x <- timeDate(as.character(1:4))
      > unclass(x)
      $.Data:
      $.Data[[1]]:
      [1] 0 0 0 0

      $.Data[[2]]:
      [1]  3600000  7200000 10800000 14400000


      $.Data.names:
      [1] "julian.day"   "milliseconds"

      $.Data.classes:
      [1] "integer" "integer"

      $format:
      [1] "%02m/%02d/%Y %02H:%02M:%02S.%03N"

      $time.zone:
      [1] "GMT"

      > x
      [1] 01/01/1960 01:00:00.000 01/01/1960 02:00:00.000 01/01/1960
      03:00:00.000
      01/01/1960 04:00:00.000
      > x@.Data[[2]] <- as.integer(jitter(x@.Data[[2]]))
      > x
      [1] 01/01/1960 00:57:17.353 01/01/1960 02:00:18.217 01/01/1960
      03:00:00.184
      01/01/1960 04:02:06.581


      It's not anywhere near perfect.  You might want to use runif()
      instead of
      jitter() or play around with the scale argument in jitter() to get
      the right
      amount of noise.

   From Sam Buttrey
      It's true that jitter() doesn't work, but you can add random noise
      directly to a timeDate object if you'd like. Consider the following
      function:


      jitter.timeDaste <- function(x, sd = 1/24)
      {
                   #
                   # Jitter timeDate data.
                   #
                   return(x + rnorm(length(x), sd = sd))
      }

      This particular function uses the Normal, but you can substitute
      whatever you'd like. You'll need to think about precisely how much
      jittering you want; I've chosen 1 hour = 1/24 day.

   From Steve McKinney
      Message 1
         jitterDate <-
           function(x,
                    ms.jitter = TRUE,
                    factor = ifelse(ms.jitter, 1000, 5),
                    shift = 0
                    )
         {
           if (ms.jitter) {
             ## Shift away from 0 if all milliseconds are 0.
             if(all(x@.Data[[2]] == 0) && (shift < 1)) shift = 1000
             ## Jitter the millisecond component
             x@.Data[[2]] <-
               as.integer(pmin(60 * 60 * 24 * 1000,
                               pmax(0,
                                    jitter(x@.Data[[2]] + shift,
                                           factor = factor))))
           } else {
             ## Jitter the julian day component
             x@.Data[[1]] <-
               as.integer(jitter(x@.Data[[1]], factor = factor))
           }

           return(x)

         }

         Examples of use:


         > td <- timeDate(c("1/1/97", "2/1/97", "mar 1, 1997"))
         > td
         [1] 01/01/1997 02/01/1997 03/01/1997
         > td@.Data
         [[1]]:
         [1] 13515 13546 13574

         [[2]]:
         [1] 0 0 0


         > td1 <- jitterDate(td)
         > td1
         [1] 01/01/1997 02/01/1997 03/01/1997
         > td1@.Data
         [[1]]:
         [1] 13515 13546 13574

         [[2]]:
         [1]  991 1003  997

         > td2 <- jitterDate(td, ms=F)
         > td2
         [1] 01/01/1997 02/01/1997 02/23/1997
         > td2@.Data
         [[1]]:
         [1] 13515 13546 13568

         [[2]]:
         [1] 0 0 0

      Message 2
         Note also that jitter() does work on timeDate
         objects in S-PLUS 7.  If you can upgrade
         to S-PLUS 7, that is one way to solve the issue.

      Message 3
         Bill Dunlap has suggested what appears to be the
         best solution, as he generally does!
         The problem in jitter() as you note is the
         is.infinite() check.  Here is a copy of the
         jitter function with that line of code replaced.
         Note that this modified function may not handle
         infinite quantities properly, so I don't recommend
         overwriting the standard jitter function.

         jitterDate <-
           function(x, factor = 1)
         {
                   if(length(x) == 0)
                               return(numeric(0))
                   ## z <- diff(range(x[is.finite(x)]))
                   z <- diff(range(x, na.rm=T))
                   if(z == 0 || is.na(z))
                               z <- 1
                   z <- factor * (z/50)
                   x + runif(length(x),  - z, z)
         }

Thank you all,
                                          
 Karen J Byron                            
 BD                                       
 tel: 201-847-5923    fax: 201-847-5887   
 E-mail: karen_byron@bd.com   Website:    
 www.bd.com                               
                                          





-----------------------------------------
*******************************************************************
IMPORTANT MESSAGE FOR RECIPIENTS IN THE U.S.A.:  This message may
constitute an advertisement of a BD group's products or services  or a
solicitation of interest in them. If this is such a message and you would
like to opt out of receiving future advertisements or solicitations from
this BD group, please forward this e-mail to optoutbygroup@bd.com.
*******************************************************************  This
message (which includes any attachments) is intended only for the
designated recipient(s).  It may contain confidential or proprietary
information and may be subject to the attorney-client  privilege or other
confidentiality protections.  If you are not a designated recipient, you
may not review, use, copy or distribute this message. If you receive this
in error, please notify the sender by reply e-mail and delete this message.
Thank you.
*******************************************************************
Corporate Headquarters Mailing Address: BD (Becton, Dickinson and Company)
1 Becton Drive Franklin Lakes, NJ 07417 U.S.A.
*******************************************************************


<Prev in Thread] Current Thread [Next in Thread>
  • jittering dates - summary of replies, Karen_Byron <=