Is there a conventional way to test for nested factors? I.e., if 'a' and 'b' are lists of same-length factors, does each level specified by 'a' correspond to exactly one level specified by 'b'? The function below seems to suffice, but I'd be happy to know of a more succinct solution, if it already exists. Thanks, Tim. --- "%nested.in%" <- function(x,f,...){ #coerce to list if(!is.list(x))x<-list(x) if(!is.list(f))f<-list(f) #collapse to vector x <- tapply(x[[1]],x) f <- tapply(f[[1]],f) #analyse return(all(sapply(lapply(split(f,x),unique),length)==1)) } CO2$Plant %nested.in% CO2[,c("Type","Treatment")] #TRUE CO2$Plant %nested.in% (CO2$uptake < mean(CO2$uptake)) #FALSE
On 6/4/07, Tim Bergsma <timb at metrumrg.com> wrote:> Is there a conventional way to test for nested factors? I.e., if 'a' > and 'b' are lists of same-length factors, does each level specified by > 'a' correspond to exactly one level specified by 'b'? > > The function below seems to suffice, but I'd be happy to know of a more > succinct solution, if it already exists.How about: "%nested%" <- function(a, b) { if (is.list(a)) a <- do.call("interaction", c(a, drop=TRUE)) if (is.list(b)) b <- do.call("interaction", c(b, drop=TRUE)) length(unique(a)) == length(unique(interaction(a, b, drop=TRUE))) } CO2$Plant %nested% CO2[,c("Type","Treatment")] #TRUE CO2$Plant %nested% (CO2$uptake < mean(CO2$uptake)) #FALSE ? Hadley
Here are two functions I wrote, 'is.nested' and 'are.crossed', that check whether a factor is nested inside antoher one, or if both are crossed: is.nested <- function (factor1,factor2) { # only one positive number per line in the f1 * f2 crosstable all(apply(table(factor1,factor2)>0,1,sum) == 1) } are.crossed <- function (factor1,factor2) { all(table(factor1,factor2) > 0 ) } Christophe Pallier www.pallier.org On 6/4/07, Tim Bergsma <timb@metrumrg.com> wrote:> > Is there a conventional way to test for nested factors? I.e., if 'a' > and 'b' are lists of same-length factors, does each level specified by > 'a' correspond to exactly one level specified by 'b'? > > The function below seems to suffice, but I'd be happy to know of a more > succinct solution, if it already exists. > > Thanks, > > Tim. > > --- > > "%nested.in%" <- function(x,f,...){ > #coerce to list > if(!is.list(x))x<-list(x) > if(!is.list(f))f<-list(f) > #collapse to vector > x <- tapply(x[[1]],x) > f <- tapply(f[[1]],f) > #analyse > return(all(sapply(lapply(split(f,x),unique),length)==1)) > } > > CO2$Plant %nested.in% CO2[,c("Type","Treatment")] #TRUE > CO2$Plant %nested.in% (CO2$uptake < mean(CO2$uptake)) #FALSE > > ______________________________________________ > R-help@stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Christophe Pallier (http://www.pallier.org) [[alternative HTML version deleted]]
Tim Bergsma wrote:> Is there a conventional way to test for nested factors? I.e., if 'a' > and 'b' are lists of same-length factors, does each level specified by > 'a' correspond to exactly one level specified by 'b'?all( tapply(b, a, function(x) length(unique(x))==1 )) J. R. M. Hosking