Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-29 Thread Martin Maechler
>>>>> Martin Maechler 
>>>>> on Mon, 26 Sep 2016 18:26:25 +0200 writes:

>>>>> Suharto Anggono Suharto Anggono 
>>>>> on Mon, 26 Sep 2016 14:51:11 + writes:

>> By "an argument named 'use.names' is included for concatenation", I 
meant something like this, that someone might try.
>>> c(as.Date("2016-01-01"), use.names=FALSE)
>> use.names 
>> "2016-01-01" "1970-01-01" 

>> See, 'use.names' is in the output. That's precisely because 'c.Date' 
doesn't have 'use.names', so that 'use.names' is absorbed into '...'.

> Yes, of course.
> Thank you for the explanation; now I understand what you meant.

> Indeed, the situation is not entirely satisfactory:

> Ideally, *both* the  'recursive' and 'use.names' arguments of
> c() should be considered arguments of only the *default* method of c(),
> not the generic.

> OTOH, c() being .Primitive() the implementation is in C only,
> and (in some sense) of *both* the generic function and the
> default method.
> The C code clearly treats  'recursive' and 'use.names' "the
> same", and has been part of R "forever".

> I think that ideally, we should aim for

> 1) The generic function  c()  only has arguments "..." (or possibly
> ---  because of history of the S4 part ---  "x, ...").

> 2) The default method has additional arguments
> 'recursive = FALSE, use.names = TRUE'
> and other methods of c() can choose if they want to also
> support one or two or none of these extras.

> Somewhat related, but in principle independent of '1)'
> and '2)' above  -- I think, because of the ".Primitive"-ness of c() --
> is the quite how 'c' should print in R.
> Currently it prints like what I say should just be the default
> method.

> Honestly, I'm not sure if it would be straightforward or even
> just relatively painless to go to  '1) + 2)' ... may change
> r71349 (to the S4 generic definition of "c") had dramatical
> effects in "package land" and hence reversion of that (with
> r71354) was necessary, for the time being.

I have just now committed a change to R-devel which on the   ?c
help page gives

| Usage:
| 
|  ## S3 Generic function
|  c(...)
|  
|  ## Default S3 method:
|  c(..., recursive = FALSE, use.names = TRUE)

and in the console, simply

| > c
| function (...)  .Primitive("c")
| > 

and am considering committing a similar change to the place
where S4 generic c() is setup in the 'methods' package.

If this persists,  methods for c(), S3 or S4, will have the
freedom to carry none, one, or both of  'recursive' and
'use.names' arguments.

  > methods(c)
  [1] c.bibentry*   c.Datec.difftimec.noquote
  [5] c.numeric_version c.person* c.POSIXct c.POSIXlt
  [9] c.warnings   

Currently, most existing c() methods have a 'recursive = FALSE'
*and* ignore a 'recursive' specification completely .. and as
Suharto has noted already, of course they do not have a
'use.names' argument yet and so do not ignore it, but treat it
as a regular argument (to be concatenated).

One consequence of this change (the above commit) is that in
principle all c() methods which have more than the '...'
arguments should be documented as "they have surprising
arguments":  They have a 'recursive' argument which is not part
of the generic.

I would say that this "should be documented" is rather a good
thing, because indeed they do silently ignore any 'recursive = foobar()'
and that should be documented, e.g., in current R (and R-devel):

  > c(Sys.Date(), recursive=quote(foobar_nonsense()))
  [1] "2016-09-29"
  > 

which is not well documented, I'd say

Martin



>> 
>> On Sun, 25/9/16, Martin Maechler  wrote:

>> Subject: Re: [Rd] Undocumented 'use.names' argument to c()
>> To: "Suharto Anggono Suharto Anggono" 
>> Cc: "R-devel" 
>> Date: Sunday, 25 September, 2016, 10:14 PM
 
>>>>> Suharto Anggono Suharto Anggono via R-devel 
>>>>> on Sun, 25 Sep 2016 14:12:10 + writes:

>>>> From comments in
>>>> 
http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/248

Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-26 Thread Martin Maechler
>>>>> Suharto Anggono Suharto Anggono 
>>>>> on Mon, 26 Sep 2016 14:51:11 + writes:

> By "an argument named 'use.names' is included for concatenation", I meant 
something like this, that someone might try.
>> c(as.Date("2016-01-01"), use.names=FALSE)
> use.names 
> "2016-01-01" "1970-01-01" 

> See, 'use.names' is in the output. That's precisely because 'c.Date' 
doesn't have 'use.names', so that 'use.names' is absorbed into '...'.

Yes, of course.
Thank you for the explanation; now I understand what you meant.

Indeed, the situation is not entirely satisfactory:

Ideally, *both* the  'recursive' and 'use.names' arguments of
c() should be considered arguments of only the *default* method of c(),
not the generic.

OTOH, c() being .Primitive() the implementation is in C only,
and (in some sense) of *both* the generic function and the
default method.
The C code clearly treats  'recursive' and 'use.names' "the
same", and has been part of R "forever".

I think that ideally, we should aim for

1) The generic function  c()  only has arguments "..." (or possibly
   ---  because of history of the S4 part ---  "x, ...").

2) The default method has additional arguments
   'recursive = FALSE, use.names = TRUE'
   and other methods of c() can choose if they want to also
   support one or two or none of these extras.

Somewhat related, but in principle independent of '1)'
and '2)' above  -- I think, because of the ".Primitive"-ness of c() --
is the quite how 'c' should print in R.
Currently it prints like what I say should just be the default
method.

Honestly, I'm not sure if it would be straightforward or even
just relatively painless to go to  '1) + 2)' ... may change
r71349 (to the S4 generic definition of "c") had dramatical
effects in "package land" and hence reversion of that (with
r71354) was necessary, for the time being.

Martin


> 
> On Sun, 25/9/16, Martin Maechler  wrote:

> Subject: Re: [Rd] Undocumented 'use.names' argument to c()
> To: "Suharto Anggono Suharto Anggono" 
> Cc: "R-devel" 
> Date: Sunday, 25 September, 2016, 10:14 PM
 
>>>>> Suharto Anggono Suharto Anggono via R-devel 
>>>>> on Sun, 25 Sep 2016 14:12:10 + writes:

>>> From comments in
>>> 
http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/24815653
>>> : The code of c() and unlist() was formerly shared but
>>> has been (long time passing) separated. From July 30,
>>> 1998, is where do_c got split into do_c and do_unlist.
>> With the implementation of 'c.Date' in R devel r71350, an
>> argument named 'use.names' is included for
>> concatenation. So, it doesn't follow the documented
>> 'c'. But, 'c.Date' is not explicitly documented in
>> Dates.Rd, that has 'c.Date' as an alias.

> I do not see any  c.Date  in R-devel with a 'use.names'; its a
> base function, hence not hidden ..

> As mentioned before, 'use.names' is used in unlist() in quite a
> few places, and such an argument also exists for

> lengths()and
> all.equal.list()

> and now c()

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-26 Thread Suharto Anggono Suharto Anggono via R-devel
By "an argument named 'use.names' is included for concatenation", I meant 
something like this, that someone might try.

> c(as.Date("2016-01-01"), use.names=FALSE)
use.names 
"2016-01-01" "1970-01-01" 

See, 'use.names' is in the output. That's precisely because 'c.Date' doesn't 
have 'use.names', so that 'use.names' is absorbed into '...'.
------------
On Sun, 25/9/16, Martin Maechler  wrote:

 Subject: Re: [Rd] Undocumented 'use.names' argument to c()

 Cc: "R-devel" 
 Date: Sunday, 25 September, 2016, 10:14 PM
 
>>>>> Suharto Anggono Suharto Anggono via R-devel 
>>>>> on Sun, 25 Sep 2016 14:12:10 + writes:

>> From comments in
>> 
http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/24815653
>> : The code of c() and unlist() was formerly shared but
>> has been (long time passing) separated. From July 30,
>> 1998, is where do_c got split into do_c and do_unlist.
> With the implementation of 'c.Date' in R devel r71350, an
> argument named 'use.names' is included for
> concatenation. So, it doesn't follow the documented
> 'c'. But, 'c.Date' is not explicitly documented in
> Dates.Rd, that has 'c.Date' as an alias.

I do not see any  c.Date  in R-devel with a 'use.names'; its a
base function, hence not hidden ..

As mentioned before, 'use.names' is used in unlist() in quite a
few places, and such an argument also exists for

lengths()and
all.equal.list()

and now c()

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-25 Thread Martin Maechler
>>>>> Suharto Anggono Suharto Anggono via R-devel 
>>>>> on Sun, 25 Sep 2016 14:12:10 + writes:

>> From comments in
>> 
http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/24815653
>> : The code of c() and unlist() was formerly shared but
>> has been (long time passing) separated. From July 30,
>> 1998, is where do_c got split into do_c and do_unlist.
> With the implementation of 'c.Date' in R devel r71350, an
> argument named 'use.names' is included for
> concatenation. So, it doesn't follow the documented
> 'c'. But, 'c.Date' is not explicitly documented in
> Dates.Rd, that has 'c.Date' as an alias.

I do not see any  c.Date  in R-devel with a 'use.names'; its a
base function, hence not hidden ..

As mentioned before, 'use.names' is used in unlist() in quite a
few places, and such an argument also exists for

lengths()   and
all.equal.list()

and now c() 

    > --------
> On Sat, 24/9/16, Martin Maechler
>  wrote:

>  Subject: Re: [Rd] Undocumented 'use.names' argument to
> c() To: "Karl Millar" 

>  Date: Saturday, 24 September, 2016, 9:12 PM
 
>>>>>> Karl Millar via R-devel 
>>>>> on Fri, 23 Sep 2016 11:12:49 -0700 writes:

>> I'd expect that a lot of the performance overhead could
>> be eliminated by simply improving the underlying code.
>> IMHO, we should ignore it in deciding the API that we
>> want here.

> I agree partially.  Even if the underlying code can be
> made faster, the 'use.names = FALSE' version will still be
> faster than the default, notably in some "long" cases.

> More further down.

>> On Fri, Sep 23, 2016 at 10:54 AM, Henrik Bengtsson
>>  wrote:
>>> I'd vote for it to stay.  It could of course suprise
>>> someone who'd expect c(list(a=1), b=2, use.names =
>>> FALSE) to generate list(a=1, b=2, use.names=FALSE).  On
>>> the upside, is the performance gain from using
>>> use.names=FALSE.  Below benchmarks show that the
>>> combining of the names attributes themselves takes
>>> ~20-25 times longer than the combining of the integers
>>> themselves.  Also, at no surprise, use.names=FALSE
>>> avoids some memory allocations.
>>> 
>>>> options(digits = 2)
>>>> 
>>>> a <- b <- c <- d <- 1:1e4 names(c) <- c names(d) <- d
>>>> 
>>>> stats <- microbenchmark::microbenchmark(
>>> + c(a, b, use.names=FALSE), + c(c, d, use.names=FALSE),
>>> + c(a, d, use.names=FALSE), + c(a, b, use.names=TRUE), +
>>> c(a, d, use.names=TRUE), + c(c, d, use.names=TRUE), +
>>> unit = "ms" + )
>>>> 
>>>> stats
>>> Unit: milliseconds expr min lq mean median uq max neval
>>> c(a, b, use.names = FALSE) 0.031 0.032 0.049 0.034 0.036
>>> 1.474 100 c(c, d, use.names = FALSE) 0.031 0.031 0.035
>>> 0.034 0.035 0.064 100 c(a, d, use.names = FALSE) 0.031
>>> 0.031 0.049 0.034 0.035 1.452 100 c(a, b, use.names =
>>> TRUE) 0.031 0.031 0.055 0.034 0.036 2.094 100 c(a, d,
>>> use.names = TRUE) 0.510 0.526 0.588 0.549 0.617 1.998
>>> 100 c(c, d, use.names = TRUE) 0.780 0.815 0.886 0.841
>>> 0.944 1.430 100
>>> 
>>>> profmem::profmem(c(c, d, use.names=FALSE))
>>> Rprofmem memory profiling of: c(c, d, use.names = FALSE)
>>> 
>>> Memory allocations: bytes calls 1 80040  total
>>> 80040
>>> 
>>>> profmem::profmem(c(c, d, use.names=TRUE))
>>> Rprofmem memory profiling of: c(c, d, use.names = TRUE)
>>> 
>>> Memory allocations: bytes calls 1 80040  2
>>> 160040  total 240080
>>> 
>>> /Henrik
>>> 
>>> On Fri, Sep 23, 2016 at 10:25 AM, William Dunlap via
>>> R-devel  wrote:
>>>> In Splus c() and unlist() called the same C code, but
>>>> with a different 'sys_index' code (the last argument to
>>>> .Internal) and c() did not consider an argument named
>>>> 'use.names' special.

> Thank you, Bill, very much, for making the historical
> context clear, and giving us the facts, the

Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-25 Thread Suharto Anggono Suharto Anggono via R-devel
>From comments in 
>http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/24815653
> : The code of c() and unlist() was formerly shared but has been (long time 
>passing) separated. From July 30, 1998, is where do_c got split into do_c and 
>do_unlist.

With the implementation of 'c.Date' in R devel r71350, an argument named 
'use.names' is included for concatenation. So, it doesn't follow the documented 
'c'. But, 'c.Date' is not explicitly documented in Dates.Rd, that has 'c.Date' 
as an alias.
------------
On Sat, 24/9/16, Martin Maechler  wrote:

 Subject: Re: [Rd] Undocumented 'use.names' argument to c()
 To: "Karl Millar" 

 Date: Saturday, 24 September, 2016, 9:12 PM
 
 >>>>> Karl Millar via R-devel 
>>>>> on Fri, 23 Sep 2016 11:12:49 -0700 writes:

> I'd expect that a lot of the performance overhead could be eliminated
> by simply improving the underlying code.  IMHO, we should ignore it in
> deciding the API that we want here.

I agree partially.  Even if the underlying code can be made
faster, the 'use.names = FALSE' version will still be faster
than the default, notably in some "long" cases.

More further down.

> On Fri, Sep 23, 2016 at 10:54 AM, Henrik Bengtsson
>  wrote:
>> I'd vote for it to stay.  It could of course suprise someone who'd
>> expect c(list(a=1), b=2, use.names = FALSE) to generate list(a=1, b=2,
>> use.names=FALSE).   On the upside, is the performance gain from using
>> use.names=FALSE.  Below benchmarks show that the combining of the
>> names attributes themselves takes ~20-25 times longer than the
>> combining of the integers themselves.  Also, at no surprise,
>> use.names=FALSE avoids some memory allocations.
>> 
>>> options(digits = 2)
>>> 
>>> a <- b <- c <- d <- 1:1e4
>>> names(c) <- c
>>> names(d) <- d
>>> 
>>> stats <- microbenchmark::microbenchmark(
>> +   c(a, b, use.names=FALSE),
>> +   c(c, d, use.names=FALSE),
>> +   c(a, d, use.names=FALSE),
>> +   c(a, b, use.names=TRUE),
>> +   c(a, d, use.names=TRUE),
>> +   c(c, d, use.names=TRUE),
>> +   unit = "ms"
>> + )
>>> 
>>> stats
>> Unit: milliseconds
>> expr   minlq  mean medianuq   max neval
>> c(a, b, use.names = FALSE) 0.031 0.032 0.049  0.034 0.036 1.474   100
>> c(c, d, use.names = FALSE) 0.031 0.031 0.035  0.034 0.035 0.064   100
>> c(a, d, use.names = FALSE) 0.031 0.031 0.049  0.034 0.035 1.452   100
>> c(a, b, use.names = TRUE) 0.031 0.031 0.055  0.034 0.036 2.094   100
>> c(a, d, use.names = TRUE) 0.510 0.526 0.588  0.549 0.617 1.998   100
>> c(c, d, use.names = TRUE) 0.780 0.815 0.886  0.841 0.944 1.430   100
>> 
>>> profmem::profmem(c(c, d, use.names=FALSE))
>> Rprofmem memory profiling of:
>> c(c, d, use.names = FALSE)
>> 
>> Memory allocations:
>> bytes  calls
>> 1 80040 
>> total 80040
>> 
>>> profmem::profmem(c(c, d, use.names=TRUE))
>> Rprofmem memory profiling of:
>> c(c, d, use.names = TRUE)
>> 
>> Memory allocations:
>> bytes  calls
>> 1  80040 
>> 2 160040 
>> total 240080
>> 
>> /Henrik
>> 
>> On Fri, Sep 23, 2016 at 10:25 AM, William Dunlap via R-devel
>>  wrote:
>>> In Splus c() and unlist() called the same C code, but with a different
>>> 'sys_index'  code (the last argument to .Internal) and c() did not 
consider
>>> an argument named 'use.names' special.

Thank you, Bill, very much, for making the historical context
clear, and giving us the facts, there.

OTOH, it is also true in R, that  c() and unlist() share code
.. quite a bit less though .. but more importantly, the very
original C code of Ross Ihaka (and possibly Robert Gentleman)
had explicitly considered both extra arguments 'recursive' and
'use.names', and not just the first.

The fact that c() has always been a .Primitive function and that
these have no formals()  had contributed to what I think to be a
documentation glitch early on, and when, quite a bit later, we've
added a fake argument list for printing, the then current
documentation was used.

This was the reason for declaring it a documentation "hole"
rather than som

Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-24 Thread Martin Maechler
> Karl Millar via R-devel 
> on Fri, 23 Sep 2016 11:12:49 -0700 writes:

> I'd expect that a lot of the performance overhead could be eliminated
> by simply improving the underlying code.  IMHO, we should ignore it in
> deciding the API that we want here.

I agree partially.  Even if the underlying code can be made
faster, the 'use.names = FALSE' version will still be faster
than the default, notably in some "long" cases.

More further down.

> On Fri, Sep 23, 2016 at 10:54 AM, Henrik Bengtsson
>  wrote:
>> I'd vote for it to stay.  It could of course suprise someone who'd
>> expect c(list(a=1), b=2, use.names = FALSE) to generate list(a=1, b=2,
>> use.names=FALSE).   On the upside, is the performance gain from using
>> use.names=FALSE.  Below benchmarks show that the combining of the
>> names attributes themselves takes ~20-25 times longer than the
>> combining of the integers themselves.  Also, at no surprise,
>> use.names=FALSE avoids some memory allocations.
>> 
>>> options(digits = 2)
>>> 
>>> a <- b <- c <- d <- 1:1e4
>>> names(c) <- c
>>> names(d) <- d
>>> 
>>> stats <- microbenchmark::microbenchmark(
>> +   c(a, b, use.names=FALSE),
>> +   c(c, d, use.names=FALSE),
>> +   c(a, d, use.names=FALSE),
>> +   c(a, b, use.names=TRUE),
>> +   c(a, d, use.names=TRUE),
>> +   c(c, d, use.names=TRUE),
>> +   unit = "ms"
>> + )
>>> 
>>> stats
>> Unit: milliseconds
>> expr   minlq  mean medianuq   max neval
>> c(a, b, use.names = FALSE) 0.031 0.032 0.049  0.034 0.036 1.474   100
>> c(c, d, use.names = FALSE) 0.031 0.031 0.035  0.034 0.035 0.064   100
>> c(a, d, use.names = FALSE) 0.031 0.031 0.049  0.034 0.035 1.452   100
>> c(a, b, use.names = TRUE) 0.031 0.031 0.055  0.034 0.036 2.094   100
>> c(a, d, use.names = TRUE) 0.510 0.526 0.588  0.549 0.617 1.998   100
>> c(c, d, use.names = TRUE) 0.780 0.815 0.886  0.841 0.944 1.430   100
>> 
>>> profmem::profmem(c(c, d, use.names=FALSE))
>> Rprofmem memory profiling of:
>> c(c, d, use.names = FALSE)
>> 
>> Memory allocations:
>> bytes  calls
>> 1 80040 
>> total 80040
>> 
>>> profmem::profmem(c(c, d, use.names=TRUE))
>> Rprofmem memory profiling of:
>> c(c, d, use.names = TRUE)
>> 
>> Memory allocations:
>> bytes  calls
>> 1  80040 
>> 2 160040 
>> total 240080
>> 
>> /Henrik
>> 
>> On Fri, Sep 23, 2016 at 10:25 AM, William Dunlap via R-devel
>>  wrote:
>>> In Splus c() and unlist() called the same C code, but with a different
>>> 'sys_index'  code (the last argument to .Internal) and c() did not 
consider
>>> an argument named 'use.names' special.

Thank you, Bill, very much, for making the historical context
clear, and giving us the facts, there.

OTOH, it is also true in R, that  c() and unlist() share code
.. quite a bit less though .. but more importantly, the very
original C code of Ross Ihaka (and possibly Robert Gentleman)
had explicitly considered both extra arguments 'recursive' and
'use.names', and not just the first.

The fact that c() has always been a .Primitive function and that
these have no formals()  had contributed to what I think to be a
documentation glitch early on, and when, quite a bit later, we've
added a fake argument list for printing, the then current
documentation was used.

This was the reason for declaring it a documentation "hole"
rather than something we do not want.

(read on)

 c
>>> function(..., recursive = F)
>>> .Internal(c(..., recursive = recursive), "S_unlist", TRUE, 1)
 unlist
>>> function(data, recursive = T, use.names = T)
>>> .Internal(unlist(data, recursive = recursive, use.names = use.names),
>>> "S_unlist", TRUE, 2)
 c(A=1,B=2,use.names=FALSE)
>>> A B use.names
>>> 1 2 0
>>> 
>>> The C code used sys_index==2 to mean 'the last  argument is the 
'use.names'
>>> argument, if sys_index==1 only the recursive argument was considered
>>> special.
>>> 
>>> Sys.funs.c:
>>> 405 S_unlist(vector *ent, vector *arglist, s_evaluator *S_evaluator)
>>> 406 {
>>> 407 int which = sys_index; boolean named, recursive, names;
>>> ...
>>> 419 args = arglist->value.tree; n = arglist->length;
>>> ...
>>> 424 names = which==2 ? logical_value(args[--n], ent, 
S_evaluator)
>>> : (which == 1);
>>> 
>>> Thus there is no historical reason for giving c() the use.names 
argument.
>>> 
>>> 
>>> Bill Dunlap
>>> TIBCO Software
>>> wdunlap tibco.com
>>> 
>>> On Fri, Sep 23, 2016 at 9:37 AM, Suharto Anggono Suharto Anggono via
>>> R-devel  wrote:
>>> 
 In S-PLUS 3.4 help on 'c' (http://www.uni-muenster.de/
 ZIV.BennoSueselbeck/s-html/helpfiles/c.html), there is n

Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-23 Thread Karl Millar via R-devel
I'd expect that a lot of the performance overhead could be eliminated
by simply improving the underlying code.  IMHO, we should ignore it in
deciding the API that we want here.

On Fri, Sep 23, 2016 at 10:54 AM, Henrik Bengtsson
 wrote:
> I'd vote for it to stay.  It could of course suprise someone who'd
> expect c(list(a=1), b=2, use.names = FALSE) to generate list(a=1, b=2,
> use.names=FALSE).   On the upside, is the performance gain from using
> use.names=FALSE.  Below benchmarks show that the combining of the
> names attributes themselves takes ~20-25 times longer than the
> combining of the integers themselves.  Also, at no surprise,
> use.names=FALSE avoids some memory allocations.
>
>> options(digits = 2)
>>
>> a <- b <- c <- d <- 1:1e4
>> names(c) <- c
>> names(d) <- d
>>
>> stats <- microbenchmark::microbenchmark(
> +   c(a, b, use.names=FALSE),
> +   c(c, d, use.names=FALSE),
> +   c(a, d, use.names=FALSE),
> +   c(a, b, use.names=TRUE),
> +   c(a, d, use.names=TRUE),
> +   c(c, d, use.names=TRUE),
> +   unit = "ms"
> + )
>>
>> stats
> Unit: milliseconds
>expr   minlq  mean medianuq   max neval
>  c(a, b, use.names = FALSE) 0.031 0.032 0.049  0.034 0.036 1.474   100
>  c(c, d, use.names = FALSE) 0.031 0.031 0.035  0.034 0.035 0.064   100
>  c(a, d, use.names = FALSE) 0.031 0.031 0.049  0.034 0.035 1.452   100
>   c(a, b, use.names = TRUE) 0.031 0.031 0.055  0.034 0.036 2.094   100
>   c(a, d, use.names = TRUE) 0.510 0.526 0.588  0.549 0.617 1.998   100
>   c(c, d, use.names = TRUE) 0.780 0.815 0.886  0.841 0.944 1.430   100
>
>> profmem::profmem(c(c, d, use.names=FALSE))
> Rprofmem memory profiling of:
> c(c, d, use.names = FALSE)
>
> Memory allocations:
>   bytes  calls
> 1 80040 
> total 80040
>
>> profmem::profmem(c(c, d, use.names=TRUE))
> Rprofmem memory profiling of:
> c(c, d, use.names = TRUE)
>
> Memory allocations:
>bytes  calls
> 1  80040 
> 2 160040 
> total 240080
>
> /Henrik
>
> On Fri, Sep 23, 2016 at 10:25 AM, William Dunlap via R-devel
>  wrote:
>> In Splus c() and unlist() called the same C code, but with a different
>> 'sys_index'  code (the last argument to .Internal) and c() did not consider
>> an argument named 'use.names' special.
>>
>>> c
>> function(..., recursive = F)
>> .Internal(c(..., recursive = recursive), "S_unlist", TRUE, 1)
>>> unlist
>> function(data, recursive = T, use.names = T)
>> .Internal(unlist(data, recursive = recursive, use.names = use.names),
>> "S_unlist", TRUE, 2)
>>> c(A=1,B=2,use.names=FALSE)
>>  A B use.names
>>  1 2 0
>>
>> The C code used sys_index==2 to mean 'the last  argument is the 'use.names'
>> argument, if sys_index==1 only the recursive argument was considered
>> special.
>>
>> Sys.funs.c:
>>  405 S_unlist(vector *ent, vector *arglist, s_evaluator *S_evaluator)
>>  406 {
>>  407 int which = sys_index; boolean named, recursive, names;
>>  ...
>>  419 args = arglist->value.tree; n = arglist->length;
>>  ...
>>  424 names = which==2 ? logical_value(args[--n], ent, S_evaluator)
>> : (which == 1);
>>
>> Thus there is no historical reason for giving c() the use.names argument.
>>
>>
>> Bill Dunlap
>> TIBCO Software
>> wdunlap tibco.com
>>
>> On Fri, Sep 23, 2016 at 9:37 AM, Suharto Anggono Suharto Anggono via
>> R-devel  wrote:
>>
>>> In S-PLUS 3.4 help on 'c' (http://www.uni-muenster.de/
>>> ZIV.BennoSueselbeck/s-html/helpfiles/c.html), there is no 'use.names'
>>> argument.
>>>
>>> Because 'c' is a generic function, I don't think that changing formal
>>> arguments is good.
>>>
>>> In R devel r71344, 'use.names' is not an argument of functions 'c.Date',
>>> 'c.POSIXct' and 'c.difftime'.
>>>
>>> Could 'use.names' be documented to be accepted by the default method of
>>> 'c', but not listed as a formal argument of 'c'? Or, could the code that
>>> handles the argument name 'use.names' be removed?
>>> 
>>> > David Winsemius 
>>> > on Tue, 20 Sep 2016 23:46:48 -0700 writes:
>>>
>>> >> On Sep 20, 2016, at 7:18 PM, Karl Millar via R-devel >> r-project.org> wrote:
>>> >>
>>> >> 'c' has an undocumented 'use.names' argument.  I'm not sure if this
>>> is
>>> >> a documentation or implementation bug.
>>>
>>> > It came up on stackoverflow a couple of years ago:
>>>
>>> > http://stackoverflow.com/questions/24815572/why-does-
>>> function-c-accept-an-undocumented-argument/24815653#24815653
>>>
>>> > At the time it appeared to me to be a documentation lag.
>>>
>>> Thank you, Karl and David,
>>> yes it is a documentation glitch ... and a bit more:  Experts know that
>>> print()ing of primitive functions is, eehm, "special".
>>>
>>> I've committed a change to R-devel ... (with the intent to port
>>> to R-patched).
>>>
>>> Martin
>>>
>>> >>
>>> >>> c(a = 1)
>>> >> a
>>> >> 1
>>> >>> c(a = 1, use.names = F)
>>> >> [1] 1
>>> >>
>>> >> Karl
>>>
>>> _

Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-23 Thread Henrik Bengtsson
I'd vote for it to stay.  It could of course suprise someone who'd
expect c(list(a=1), b=2, use.names = FALSE) to generate list(a=1, b=2,
use.names=FALSE).   On the upside, is the performance gain from using
use.names=FALSE.  Below benchmarks show that the combining of the
names attributes themselves takes ~20-25 times longer than the
combining of the integers themselves.  Also, at no surprise,
use.names=FALSE avoids some memory allocations.

> options(digits = 2)
>
> a <- b <- c <- d <- 1:1e4
> names(c) <- c
> names(d) <- d
>
> stats <- microbenchmark::microbenchmark(
+   c(a, b, use.names=FALSE),
+   c(c, d, use.names=FALSE),
+   c(a, d, use.names=FALSE),
+   c(a, b, use.names=TRUE),
+   c(a, d, use.names=TRUE),
+   c(c, d, use.names=TRUE),
+   unit = "ms"
+ )
>
> stats
Unit: milliseconds
   expr   minlq  mean medianuq   max neval
 c(a, b, use.names = FALSE) 0.031 0.032 0.049  0.034 0.036 1.474   100
 c(c, d, use.names = FALSE) 0.031 0.031 0.035  0.034 0.035 0.064   100
 c(a, d, use.names = FALSE) 0.031 0.031 0.049  0.034 0.035 1.452   100
  c(a, b, use.names = TRUE) 0.031 0.031 0.055  0.034 0.036 2.094   100
  c(a, d, use.names = TRUE) 0.510 0.526 0.588  0.549 0.617 1.998   100
  c(c, d, use.names = TRUE) 0.780 0.815 0.886  0.841 0.944 1.430   100

> profmem::profmem(c(c, d, use.names=FALSE))
Rprofmem memory profiling of:
c(c, d, use.names = FALSE)

Memory allocations:
  bytes  calls
1 80040 
total 80040

> profmem::profmem(c(c, d, use.names=TRUE))
Rprofmem memory profiling of:
c(c, d, use.names = TRUE)

Memory allocations:
   bytes  calls
1  80040 
2 160040 
total 240080

/Henrik

On Fri, Sep 23, 2016 at 10:25 AM, William Dunlap via R-devel
 wrote:
> In Splus c() and unlist() called the same C code, but with a different
> 'sys_index'  code (the last argument to .Internal) and c() did not consider
> an argument named 'use.names' special.
>
>> c
> function(..., recursive = F)
> .Internal(c(..., recursive = recursive), "S_unlist", TRUE, 1)
>> unlist
> function(data, recursive = T, use.names = T)
> .Internal(unlist(data, recursive = recursive, use.names = use.names),
> "S_unlist", TRUE, 2)
>> c(A=1,B=2,use.names=FALSE)
>  A B use.names
>  1 2 0
>
> The C code used sys_index==2 to mean 'the last  argument is the 'use.names'
> argument, if sys_index==1 only the recursive argument was considered
> special.
>
> Sys.funs.c:
>  405 S_unlist(vector *ent, vector *arglist, s_evaluator *S_evaluator)
>  406 {
>  407 int which = sys_index; boolean named, recursive, names;
>  ...
>  419 args = arglist->value.tree; n = arglist->length;
>  ...
>  424 names = which==2 ? logical_value(args[--n], ent, S_evaluator)
> : (which == 1);
>
> Thus there is no historical reason for giving c() the use.names argument.
>
>
> Bill Dunlap
> TIBCO Software
> wdunlap tibco.com
>
> On Fri, Sep 23, 2016 at 9:37 AM, Suharto Anggono Suharto Anggono via
> R-devel  wrote:
>
>> In S-PLUS 3.4 help on 'c' (http://www.uni-muenster.de/
>> ZIV.BennoSueselbeck/s-html/helpfiles/c.html), there is no 'use.names'
>> argument.
>>
>> Because 'c' is a generic function, I don't think that changing formal
>> arguments is good.
>>
>> In R devel r71344, 'use.names' is not an argument of functions 'c.Date',
>> 'c.POSIXct' and 'c.difftime'.
>>
>> Could 'use.names' be documented to be accepted by the default method of
>> 'c', but not listed as a formal argument of 'c'? Or, could the code that
>> handles the argument name 'use.names' be removed?
>> 
>> > David Winsemius 
>> > on Tue, 20 Sep 2016 23:46:48 -0700 writes:
>>
>> >> On Sep 20, 2016, at 7:18 PM, Karl Millar via R-devel > r-project.org> wrote:
>> >>
>> >> 'c' has an undocumented 'use.names' argument.  I'm not sure if this
>> is
>> >> a documentation or implementation bug.
>>
>> > It came up on stackoverflow a couple of years ago:
>>
>> > http://stackoverflow.com/questions/24815572/why-does-
>> function-c-accept-an-undocumented-argument/24815653#24815653
>>
>> > At the time it appeared to me to be a documentation lag.
>>
>> Thank you, Karl and David,
>> yes it is a documentation glitch ... and a bit more:  Experts know that
>> print()ing of primitive functions is, eehm, "special".
>>
>> I've committed a change to R-devel ... (with the intent to port
>> to R-patched).
>>
>> Martin
>>
>> >>
>> >>> c(a = 1)
>> >> a
>> >> 1
>> >>> c(a = 1, use.names = F)
>> >> [1] 1
>> >>
>> >> Karl
>>
>> __
>> R-devel@r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
> [[alternative HTML version deleted]]
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-23 Thread William Dunlap via R-devel
In Splus c() and unlist() called the same C code, but with a different
'sys_index'  code (the last argument to .Internal) and c() did not consider
an argument named 'use.names' special.

> c
function(..., recursive = F)
.Internal(c(..., recursive = recursive), "S_unlist", TRUE, 1)
> unlist
function(data, recursive = T, use.names = T)
.Internal(unlist(data, recursive = recursive, use.names = use.names),
"S_unlist", TRUE, 2)
> c(A=1,B=2,use.names=FALSE)
 A B use.names
 1 2 0

The C code used sys_index==2 to mean 'the last  argument is the 'use.names'
argument, if sys_index==1 only the recursive argument was considered
special.

Sys.funs.c:
 405 S_unlist(vector *ent, vector *arglist, s_evaluator *S_evaluator)
 406 {
 407 int which = sys_index; boolean named, recursive, names;
 ...
 419 args = arglist->value.tree; n = arglist->length;
 ...
 424 names = which==2 ? logical_value(args[--n], ent, S_evaluator)
: (which == 1);

Thus there is no historical reason for giving c() the use.names argument.


Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Fri, Sep 23, 2016 at 9:37 AM, Suharto Anggono Suharto Anggono via
R-devel  wrote:

> In S-PLUS 3.4 help on 'c' (http://www.uni-muenster.de/
> ZIV.BennoSueselbeck/s-html/helpfiles/c.html), there is no 'use.names'
> argument.
>
> Because 'c' is a generic function, I don't think that changing formal
> arguments is good.
>
> In R devel r71344, 'use.names' is not an argument of functions 'c.Date',
> 'c.POSIXct' and 'c.difftime'.
>
> Could 'use.names' be documented to be accepted by the default method of
> 'c', but not listed as a formal argument of 'c'? Or, could the code that
> handles the argument name 'use.names' be removed?
> 
> > David Winsemius 
> > on Tue, 20 Sep 2016 23:46:48 -0700 writes:
>
> >> On Sep 20, 2016, at 7:18 PM, Karl Millar via R-devel  r-project.org> wrote:
> >>
> >> 'c' has an undocumented 'use.names' argument.  I'm not sure if this
> is
> >> a documentation or implementation bug.
>
> > It came up on stackoverflow a couple of years ago:
>
> > http://stackoverflow.com/questions/24815572/why-does-
> function-c-accept-an-undocumented-argument/24815653#24815653
>
> > At the time it appeared to me to be a documentation lag.
>
> Thank you, Karl and David,
> yes it is a documentation glitch ... and a bit more:  Experts know that
> print()ing of primitive functions is, eehm, "special".
>
> I've committed a change to R-devel ... (with the intent to port
> to R-patched).
>
> Martin
>
> >>
> >>> c(a = 1)
> >> a
> >> 1
> >>> c(a = 1, use.names = F)
> >> [1] 1
> >>
> >> Karl
>
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>

[[alternative HTML version deleted]]

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-23 Thread Suharto Anggono Suharto Anggono via R-devel
In S-PLUS 3.4 help on 'c' 
(http://www.uni-muenster.de/ZIV.BennoSueselbeck/s-html/helpfiles/c.html), there 
is no 'use.names' argument.

Because 'c' is a generic function, I don't think that changing formal arguments 
is good.

In R devel r71344, 'use.names' is not an argument of functions 'c.Date', 
'c.POSIXct' and 'c.difftime'.

Could 'use.names' be documented to be accepted by the default method of 'c', 
but not listed as a formal argument of 'c'? Or, could the code that handles the 
argument name 'use.names' be removed?

> David Winsemius 
> on Tue, 20 Sep 2016 23:46:48 -0700 writes:

>> On Sep 20, 2016, at 7:18 PM, Karl Millar via R-devel  wrote:
>> 
>> 'c' has an undocumented 'use.names' argument.  I'm not sure if this is
>> a documentation or implementation bug.

> It came up on stackoverflow a couple of years ago:

> 
http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/24815653#24815653

> At the time it appeared to me to be a documentation lag.

Thank you, Karl and David,
yes it is a documentation glitch ... and a bit more:  Experts know that
print()ing of primitive functions is, eehm, "special".

I've committed a change to R-devel ... (with the intent to port
to R-patched).

Martin

>> 
>>> c(a = 1)
>> a
>> 1
>>> c(a = 1, use.names = F)
>> [1] 1
>> 
>> Karl

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-21 Thread Martin Maechler
> David Winsemius 
> on Tue, 20 Sep 2016 23:46:48 -0700 writes:

>> On Sep 20, 2016, at 7:18 PM, Karl Millar via R-devel 
 wrote:
>> 
>> 'c' has an undocumented 'use.names' argument.  I'm not sure if this is
>> a documentation or implementation bug.

> It came up on stackoverflow a couple of years ago:

> 
http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/24815653#24815653

> At the time it appeared to me to be a documentation lag.

Thank you, Karl and David,
yes it is a documentation glitch ... and a bit more:  Experts know that
print()ing of primitive functions is, eehm, "special".

I've committed a change to R-devel ... (with the intent to port
to R-patched).

Martin

>> 
>>> c(a = 1)
>> a
>> 1
>>> c(a = 1, use.names = F)
>> [1] 1
>> 
>> Karl

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


Re: [Rd] Undocumented 'use.names' argument to c()

2016-09-20 Thread David Winsemius

> On Sep 20, 2016, at 7:18 PM, Karl Millar via R-devel  
> wrote:
> 
> 'c' has an undocumented 'use.names' argument.  I'm not sure if this is
> a documentation or implementation bug.

It came up on stackoverflow a couple of years ago:

http://stackoverflow.com/questions/24815572/why-does-function-c-accept-an-undocumented-argument/24815653#24815653

At the time it appeared to me to be a documentation lag.


> 
>> c(a = 1)
> a
> 1
>> c(a = 1, use.names = F)
> [1] 1
> 
> Karl
> 
> __
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

David Winsemius
Alameda, CA, USA

__
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel