Forgive me if this has been asked many times before, but I couldn't find
anything on the mailing lists.
I'd expect apply(m, 1, foo) not to call `foo` if m is a matrix with zero
rows.
In fact:
m <- matrix(NA, 0, 5)
apply(m, 1, function (x) {cat("Called...\n"); print(x)})
## Called...
## [1] FALSE FALSE FALSE FALSE FALSE
Similarly for apply(m, 2,...) if m has no columns.
Is there a reason for this? Could it be documented?
David
--
Sent from Gmail Mobile
[[alternative HTML version deleted]]
>>>>> David Hugh-Jones >>>>> on Mon, 30 Jul 2018 05:33:19 +0100 writes:> Forgive me if this has been asked many times before, but I > couldn't find anything on the mailing lists. > I'd expect apply(m, 1, foo) not to call `foo` if m is a > matrix with zero rows. In fact: > m <- matrix(NA, 0, 5) > apply(m, 1, function (x) {cat("Called...\n"); print(x)}) > ## Called... > ## [1] FALSE FALSE FALSE FALSE FALSE > Similarly for apply(m, 2,...) if m has no columns. Is > there a reason for this? Yes : The reverse is really true for almost all basic R functions: They *are* called and give an "empty" result automatically when the main argument is empty. What you basicaly propose is to add an extra if(<length 0 input>) return(<correspondingly formatted length-0 output>) to all R functions. While that makes sense for high-level R functions that do a lot of things, this would really be a bad idea in general : This would make all of these basic functions larger {more to maintain} and slightly slower for all non-zero cases just to make them slightly faster for the rare zero-length case. Martin Maechler ETH Zurich and R core Team
Hi Martin, Fair enough for R functions in general. But the behaviour of apply violates the expectation that apply(m, 1, fun) calls fun n times when m has n rows. That seems pretty basic. Also, I understand from your argument why it makes sense to call apply and return a special result (presumably NULL) for an empty argument; but why should apply call fun? Cheers David On Mon, 30 Jul 2018 at 08:41, Martin Maechler <maechler at stat.math.ethz.ch> wrote:> >>>>> David Hugh-Jones > >>>>> on Mon, 30 Jul 2018 05:33:19 +0100 writes: > > > Forgive me if this has been asked many times before, but I > > couldn't find anything on the mailing lists. > > > I'd expect apply(m, 1, foo) not to call `foo` if m is a > > matrix with zero rows. In fact: > > > m <- matrix(NA, 0, 5) > > apply(m, 1, function (x) {cat("Called...\n"); print(x)}) > > ## Called... > > ## [1] FALSE FALSE FALSE FALSE FALSE > > > > Similarly for apply(m, 2,...) if m has no columns. Is > > there a reason for this? > > Yes : > > The reverse is really true for almost all basic R functions: > > They *are* called and give an "empty" result automatically > when the main argument is empty. > > What you basicaly propose is to add an extra > > if(<length 0 input>) > return(<correspondingly formatted length-0 output>) > > to all R functions. While that makes sense for high-level R > functions that do a lot of things, this would really be a bad > idea in general : > > This would make all of these basic functions larger {more to maintain} and > slightly slower for all non-zero cases just to make them > slightly faster for the rare zero-length case. > > Martin Maechler > ETH Zurich and R core Team > > --Sent from Gmail Mobile [[alternative HTML version deleted]]
Hi David,
Besides Martins point, there is also the issue that for a lot of cases you
would still like to have the right class returned.
Right now these are returns:
> apply(matrix(NA_integer_,0,5), 1, class)
character(0)
> apply(matrix(NA_integer_,0,5), 1, identity)
integer(0)
> apply(matrix(NA,0,5), 1, identity)
logical(0)
In your case, these would all return NULL, so I think there is value in
running FUN at least once (Say if you'd want to check if FUN always returns
the right class).
And from a philosophical point of view, R is mostly a functional programming
language, I think if you want side-effects a for-loop would look better.
Best regards,
Emil Bode
Data-analyst
+31 6 43 83 89 33
emil.bode at dans.knaw.nl
DANS: Netherlands Institute for Permanent Access to Digital Research
Resources
Anna van Saksenlaan 51 | 2593 HW Den Haag | +31 70 349 44 50 | info at
dans.knaw.nl <mailto:info at dans.kn> | dans.knaw.nl
<applewebdata://71F677F0-6872-45F3-A6C4-4972BF87185B/www.dans.knaw.nl>
DANS is an institute of the Dutch Academy KNAW <http://knaw.nl/nl> and
funding organisation NWO <http://www.nwo.nl/>.
On 30/07/2018, 11:12, "R-devel on behalf of David Hugh-Jones"
<r-devel-bounces at r-project.org on behalf of davidhughjones at
gmail.com> wrote:
Hi Martin,
Fair enough for R functions in general. But the behaviour of apply
violates
the expectation that apply(m, 1, fun) calls fun n times when m has n
rows.
That seems pretty basic.
Also, I understand from your argument why it makes sense to call apply
and
return a special result (presumably NULL) for an empty argument; but why
should apply call fun?
Cheers
David
On Mon, 30 Jul 2018 at 08:41, Martin Maechler <maechler at
stat.math.ethz.ch>
wrote:
> >>>>> David Hugh-Jones
> >>>>> on Mon, 30 Jul 2018 05:33:19 +0100 writes:
>
> > Forgive me if this has been asked many times before, but I
> > couldn't find anything on the mailing lists.
>
> > I'd expect apply(m, 1, foo) not to call `foo` if m is
a
> > matrix with zero rows. In fact:
>
> > m <- matrix(NA, 0, 5)
> > apply(m, 1, function (x) {cat("Called...\n");
print(x)})
> > ## Called...
> > ## [1] FALSE FALSE FALSE FALSE FALSE
>
>
> > Similarly for apply(m, 2,...) if m has no columns. Is
> > there a reason for this?
>
> Yes :
>
> The reverse is really true for almost all basic R functions:
>
> They *are* called and give an "empty" result
automatically
> when the main argument is empty.
>
> What you basicaly propose is to add an extra
>
> if(<length 0 input>)
> return(<correspondingly formatted length-0 output>)
>
> to all R functions. While that makes sense for high-level R
> functions that do a lot of things, this would really be a bad
> idea in general :
>
> This would make all of these basic functions larger {more to
maintain} and
> slightly slower for all non-zero cases just to make them
> slightly faster for the rare zero-length case.
>
> Martin Maechler
> ETH Zurich and R core Team
>
> --
Sent from Gmail Mobile
[[alternative HTML version deleted]]
______________________________________________
R-devel at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Try pmap and related functions in purrr:
pmap(as.data.frame(m), ~ { cat("Called...\n"); print(c(...)) })
## list()
On Mon, Jul 30, 2018 at 12:33 AM, David Hugh-Jones
<davidhughjones at gmail.com> wrote:> Forgive me if this has been asked many times before, but I couldn't
find
> anything on the mailing lists.
>
> I'd expect apply(m, 1, foo) not to call `foo` if m is a matrix with
zero
> rows.
> In fact:
>
> m <- matrix(NA, 0, 5)
> apply(m, 1, function (x) {cat("Called...\n"); print(x)})
> ## Called...
> ## [1] FALSE FALSE FALSE FALSE FALSE
>
> Similarly for apply(m, 2,...) if m has no columns.
> Is there a reason for this? Could it be documented?
>
> David
> --
> Sent from Gmail Mobile
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
--
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com
Interesting discussion. I'm not wholly convinced by Martin's and
Emil's
arguments. The behaviour seems to violate an obvious expectation (fun is
called once per row) to satisfy a subtle one (result has a guaranteed
dimension and type).
In any case, here's a suggested chunk of rd to go at the end of the
"Value":
If \code{dim(X)[MARGIN]} is zero, then \code{FUN} is called once, with an
argument of the appropriate dimensions. The argument's type is the same as
\code{typeof(m)}, and the argument values are those returned by
\code{vector(typeof(m))}. For example, if m is numeric, the argument will
be a vector (or matrix or array) of zeroes. The type and length of the
value returned by \code{FUN} is used to determine the type of the result.
And at the end of "Details":
\code{FUN} is always called at least once, see below.
David
On Mon, 30 Jul 2018 at 15:05, Gabor Grothendieck <ggrothendieck at
gmail.com>
wrote:
> Try pmap and related functions in purrr:
>
> pmap(as.data.frame(m), ~ { cat("Called...\n"); print(c(...)) })
> ## list()
>
> On Mon, Jul 30, 2018 at 12:33 AM, David Hugh-Jones
> <davidhughjones at gmail.com> wrote:
> > Forgive me if this has been asked many times before, but I
couldn't find
> > anything on the mailing lists.
> >
> > I'd expect apply(m, 1, foo) not to call `foo` if m is a matrix
with zero
> > rows.
> > In fact:
> >
> > m <- matrix(NA, 0, 5)
> > apply(m, 1, function (x) {cat("Called...\n"); print(x)})
> > ## Called...
> > ## [1] FALSE FALSE FALSE FALSE FALSE
> >
> > Similarly for apply(m, 2,...) if m has no columns.
> > Is there a reason for this? Could it be documented?
> >
> > David
> > --
> > Sent from Gmail Mobile
> >
> > [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > R-devel at r-project.org mailing list
> > https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
>
> --
> Statistics & Software Consulting
> GKX Group, GKX Associates Inc.
> tel: 1-877-GKX-GROUP
> email: ggrothendieck at gmail.com
>
[[alternative HTML version deleted]]
Maybe Matching Threads
- Relevel confusing with numeric value
- Inconsistencies when extracting with non-integer numeric indices near zero
- oddity in transform
- sys.call() inside replacement functions incorrectly returns *tmp*
- Bug when calling system/system2 (and request for Bugzilla account)