From maechler at stat.math.ethz.ch  Wed Jul 19 09:30:15 2006
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Wed, 19 Jul 2006 09:30:15 +0200
Subject: [Rd] Patch to allow negative argument in head() and tail()
In-Reply-To: <20060718214153.GA5151@alcyon.progiciels-bpi.ca>
References: <200607171503.34713.vincent.goulet@act.ulaval.ca>
	<17596.40686.710925.321109@stat.math.ethz.ch>
	<200607181356.06360.vincent.goulet@act.ulaval.ca>
	<20060718214153.GA5151@alcyon.progiciels-bpi.ca>
Message-ID: <17597.57223.151500.824538@stat.math.ethz.ch>

>>>>> "FrPi" == Fran?ois Pinard <pinard at iro.umontreal.ca>
>>>>>     on Tue, 18 Jul 2006 17:41:53 -0400 writes:

    FrPi> [Vincent Goulet]
    >> For me, this usage of head() and tail() is, at first,
    >> completely unintuitive since I more used to, say, "start
    >> from the beginning (head) of the vector and drop the
    >> first n elements" than "return the end of the vector
    >> except the first n elements". But I must agree your
    >> convention does make sense!

    FrPi> Vincent -- bonjour!, Martin -- hi! and all others -- hello! :-)
:-)

    FrPi> The usual head and tail Unix utilities, as found
    FrPi> within GNU Coreutils, have conventions for negative
    FrPi> numbers.  See:

      $ seq 10 | head -n-3
      1
      2
      3
      4
      5
      6
      7
      $ seq 10 | tail -n-3
      8
      9
      10
      $

    FrPi> Of course, these do not rule what R should do in any
    FrPi> way.  Yet, it is sometimes convenient and even elegant
    FrPi> when tools having similar names have similar
    FrPi> behaviour.  Despite application domains are different,
    FrPi> it's worth pondering such similarities, when these are
    FrPi> easily possible.

Thank you for the good suggestion.
However Peter Dalgaard has beaten you here -- in a non-public
mail though.

An excerpt of my answer (of yesterday) to his mail:

  Regarding unix command line compatibility:
  Note that there, 'tail'  is *really* not what we want to imitate:

  "3" is the same as "-3" but different from "+3" :
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  $ for N in 3 -3 +3 ; do echo "  $N :"; echo '  ---' ; tail -n $N /tmp/lib12.txt ; done

    3 :
    ---
  10                  "target")))
  11              if (!res)
  12                  stop(gettextf("This is R %s, package '%s' needs %s %s",
    -3 :
    ---
  10                  "target")))
  11              if (!res)
  12                  stop(gettextf("This is R %s, package '%s' needs %s %s",
    +3 :
    ---
  3       verbose = getOption("verbose"), version)
  4   {
  5       testRversion <- function(pkgInfo, pkgname, pkgpath) {
  6           current <- getRversion()
  7           if (length(Rdeps <- pkgInfo$Rdepends) > 1) {
  8               target <- Rdeps$version
  9               res <- eval(parse(text = paste("current", Rdeps$op,
  10                  "target")))
  11              if (!res)
  12                  stop(gettextf("This is R %s, package '%s' needs %s %s",

----------

I know that there is some "good" reason for the behavior of
'tail' in "Unix" 
  { tail -3 === tail -n  3   and
    tail -3 === tail -n -3      }

but of course, we can't be compatible here, because in S
(and most reasonable languages :-) 
"3 == +3"  and  "3 != -3" !

Martin



[Rd] Patch to allow negative argument in head() and tail()
Martin Maechler