Reputation: 22293
This answer brought up the question of how the ellipsis feature in R
handles empty arguments. Apparently an empty argument in ...
works sometimes (see lapply
version below) but not other times (see sapply
version). Here's the example:
lst <- list(x=matrix(1))
lapply(lst, "[", 1, )
# $x
# [1] 1
sapply(lst, "[", 1, )
# Error in lapply(X = X, FUN = FUN, ...) :
# argument is missing, with no default
From what I can tell, sapply
actually just reuses its ...
arguments when calling lapply
. So I don't understand why lapply
works but sapply
doesn't. Can anybody explain this behavior.
In the sapply
help it states that
sapply(*, simplify = FALSE, USE.NAMES = FALSE) is equivalent to lapply(*).
However, I get the same results as above for the following:
lapply(lst, "[", i=1, j=)
sapply(lst, "[", i=1, j=, simplify=FALSE, USE.NAMES=FALSE)
By the way, I know that just adding TRUE
would solve the issue in this case, but I'm more interested in why there is a difference, not how to solve it. I'm actually more surprised that it works for the lapply
case than that it doesn't for the sapply
one.
Upvotes: 4
Views: 380
Reputation: 3110
Because I am not a C master, at all, I can only show you what the differences are between how sapply
and lapply
are represented internally. And maybe someone else can build on this answer a little bit.
So for sapply
: we'll look at https://github.com/SurajGupta/r-source/blob/master/src/library/base/R/sapply.R
And for lapply: https://github.com/SurajGupta/r-source/blob/master/src/library/base/R/lapply.R
This shows that although sapply
calls lapply
it then also calls simplify2array
which could be one of the issues, but my intuition is telling me that this isn't the issue.
lapply
ends up using .Internal(lapply(X,FUN))
which ends up calling do_lapply
within the C source code here: https://github.com/SurajGupta/r-source/blob/91aaa43312da6b0e6906ef221fd7756dc0459843/src/main/apply.c
My guess is that because sapply
inherently passes two parameters into SEXP args
the ...
argument is trying to create the SEXP args
of sapply
with everything after sapply(lst, "[",
and because it can't figure out what to do with either 1,
or j=
before it gets to
simplify=FALSE, USE.NAMES=FALSE
, it fails. Although that would just be my guess. Whereas lapply
doesn't have the additional arguments being forced into SEXP args
so it can handle 1,
or j=
in a different way.
This post, Understanding how .Internal C functions are handled in R, does a very nice job explaining some of the nitty-gritty C stuff.
Hope this helps explain the differences to some degree, or at least can serve as a starting point for someone with greater R-devel skills.
Upvotes: 1