On Mon, Feb 20, 2017 at 7:31 AM, Martin Maechler
wrote:
>> Hervé Pagès
>> on Tue, 14 Feb 2017 17:10:05 -0800 writes:
>
> > Hi, tapply() will work on any object 'X' that has a length
> > and supports single-bracket subsetting.
> Hervé Pagès
> on Tue, 14 Feb 2017 17:10:05 -0800 writes:
> Hi, tapply() will work on any object 'X' that has a length
> and supports single-bracket subsetting. These objects are
> sometimes called "vector-like" objects. Atomic vectors,
> lists,
You could also call this "interesting example" a bug.
Clearly not enough code reuse in the implementation of tapply().
Instead of the current 25 lines of code, it could be a simple
wrapper around split() and sapply() e.g.. something like:
tapply2 <- function(X, INDEX, FUN=NULL, ...,
It seems like this should be consistent with split(), since that's
what actually powers the behaviour.
Reading the description for split leads to this rather interesting example:
tapply(mtcars, 1:11, I)
Hadley
On Tue, Feb 14, 2017 at 7:10 PM, Hervé Pagès wrote:
> Hi,
>
>
On 02/14/2017 06:39 PM, Bert Gunter wrote:
Yes, exactly.
So my point is that this:
"X: a vector-like object that supports subsetting with `[`, typically
an atomic vector."
is incorrect, or at least a bit opaque, without further emphasizing
that FUN must accept the result of "[".
Yes, exactly.
So my point is that this:
"X: a vector-like object that supports subsetting with `[`, typically
an atomic vector."
is incorrect, or at least a bit opaque, without further emphasizing
that FUN must accept the result of "[". With atomic vectors, the error
that you produced
Right. More precisely the function passed thru the FUN argument must
work on the subsets of X generated internally by tapply(). You can
actually see these subsets by passing the identity function:
X <- letters[1:10]
INDEX <- c(rep(1,5),rep(2,5))
tapply(X, INDEX, FUN=identity)
# $`1`
#
The problem with Bert's second example is that sum doesn't work on a list.
The tapply worked correctly.
> unlist(l[1:5])
[1] 1 2 3 4 5
> sum(l[1:5])
Error in sum(l[1:5]) : invalid 'type' (list) of argument
On Tue, Feb 14, 2017 at 8:28 PM, Bert Gunter wrote:
> Hervé:
>
Hervé:
Kindly explain this, then:
> l <- as.list(1:10)
> is.atomic(l) # FALSE
[1] FALSE
> index <- c(rep(1,5),rep(2,5))
>
>
> tapply(l,index,unlist)
$`1`
[1] 1 2 3 4 5
$`2`
[1] 6 7 8 9 10
>
> ## But
>
> tapply(l,index, sum)
Error in FUN(X[[i]], ...) : invalid 'type' (list) of argument
Hi,
tapply() will work on any object 'X' that has a length and supports
single-bracket subsetting. These objects are sometimes called
"vector-like" objects. Atomic vectors, lists, S4 objects with a "length"
and "[" method, etc... are examples of "vector-like" objects.
So instead of saying
X:
Did you ever receive a reply to this?
Note that for your example:
> tapply(l,index,sum)
Error in FUN(X[[i]], ...) : invalid 'type' (list) of argument
A list is definitely not atomic (is.recursive(l) ).
So it looks like a "quirk" that FUN = unlist doesn't raise an error.
Cheers,
Bert
Bert
In the help page of ?tapply it says that the first argument (X) is "an
atomic object, typically a vector."
However, tapply seems to be able to handle list objects. For example:
###
l <- as.list(1:10)
is.atomic(l) # FALSE
index <- c(rep(1,5),rep(2,5))
tapply(l,index,unlist)
>
12 matches
Mail list logo