Suharto Anggono Suharto Anggono
2016-Sep-26 14:51 UTC
[Rd] Undocumented 'use.names' argument to c()
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 <maechler at stat.math.ethz.ch> wrote: Subject: Re: [Rd] Undocumented 'use.names' argument to c() Cc: "R-devel" <R-devel at r-project.org> Date: Sunday, 25 September, 2016, 10:14 PM>>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org> >>>>> on Sun, 25 Sep 2016 14:12:10 +0000 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()
>>>>> Suharto Anggono Suharto Anggono <suharto_anggono at yahoo.com> >>>>> on Mon, 26 Sep 2016 14:51:11 +0000 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 <maechler at stat.math.ethz.ch> wrote: > Subject: Re: [Rd] Undocumented 'use.names' argument to c() > To: "Suharto Anggono Suharto Anggono" <suharto_anggono at yahoo.com> > Cc: "R-devel" <R-devel at r-project.org> > Date: Sunday, 25 September, 2016, 10:14 PM>>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org> >>>>> on Sun, 25 Sep 2016 14:12:10 +0000 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()
>>>>> Martin Maechler <maechler at stat.math.ethz.ch> >>>>> on Mon, 26 Sep 2016 18:26:25 +0200 writes:>>>>> Suharto Anggono Suharto Anggono <suharto_anggono at yahoo.com> >>>>> on Mon, 26 Sep 2016 14:51:11 +0000 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.Date c.difftime c.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 <maechler at stat.math.ethz.ch> wrote: >> Subject: Re: [Rd] Undocumented 'use.names' argument to c() >> To: "Suharto Anggono Suharto Anggono" <suharto_anggono at yahoo.com> >> Cc: "R-devel" <R-devel at r-project.org> >> Date: Sunday, 25 September, 2016, 10:14 PM>>>>> Suharto Anggono Suharto Anggono via R-devel <r-devel at r-project.org> >>>>> on Sun, 25 Sep 2016 14:12:10 +0000 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()