Reputation: 93813
Take this simple vector x
and two grouping variables, g1
and g2
x <- 1:10
g1 <- rep(1:2, each=5)
g2 <- rep(1:3, c(2,3,5))
There are a number of groups in an interaction
of these variables that are not represented in this current data.
table(interaction(g1,g2))
#1.1 2.1 1.2 2.2 1.3 2.3
# 2 0 3 0 0 5
This causes rare errors that can essentially be boiled down to something simple like:
ave(x, list(g1,g2), FUN=function(x) if(length(x)==0) stop() else length(x) )
#Error in FUN(X[[i]], ...) :
Now, I see no reason why this should be the case, given that the result of ave
should always just be the same length as x
, with unrepresented interaction of groups discarded.
This is an easy fix to ave
, such as:
ave2 <- function (x, ..., FUN = mean)
{
if (missing(...))
x[] <- FUN(x)
else {
# the only real edit is the following line
g <- interaction(..., drop=TRUE)
split(x, g) <- lapply(split(x, g), FUN)
}
x
}
...which then gives the appropriate result.
ave2(x, list(g1,g2), FUN=function(x) if(length(x)==0) stop() else length(x) )
#[1] 2 2 3 3 3 5 5 5 5 5
I guess before I go and suggest the following to a bug tracker, am I overlooking something simple as to why ave
should not have drop=TRUE
added?
So the question is, is there a circumstance where ave
ever needs to know about unrepresented interactions?
Upvotes: 2
Views: 62
Reputation: 24480
You can pass the drop
argument to ave
too:
ave(x,list(g1,g2),drop=TRUE, FUN=function(x) if(length(x)==0) stop() else length(x) )
#[1] 2 2 3 3 3 5 5 5 5 5
Upvotes: 1
Reputation: 263362
Not a problem with ave
, but rather stop
is not designed to return an item of length 0. Try this instead:
ave(x, list(g1,g2), FUN=function(x) if(length(x)==0) {vector("numeric",0)
}else length(x) )
[1] 2 2 3 3 3 5 5 5 5 5
Upvotes: 1