From marc_schwartz at comcast.net  Tue Nov 14 18:51:25 2006
From: marc_schwartz at comcast.net (Marc Schwartz)
Date: Tue, 14 Nov 2006 11:51:25 -0600
Subject: [Rd] c.factor
In-Reply-To: <946928E281E8FD4B91D5B2CC3C91967D6AA9A0@lnex01.CONCORDIAFUNDS.COM>
References: <946928E281E8FD4B91D5B2CC3C91967D6AA9A0@lnex01.CONCORDIAFUNDS.COM>
Message-ID: <1163526685.4492.20.camel@localhost.localdomain>

On Tue, 2006-11-14 at 16:36 +0000, Matthew Dowle wrote:
> Hi,
> 
> Given factors x and y,  c(x,y) does not seem to return a useful result :
> > x
> [1] a b c d e
> Levels: a b c d e
> > y
> [1] d e f g h
> Levels: d e f g h
> > c(x,y)
>  [1] 1 2 3 4 5 1 2 3 4 5
> > 
> 
> Is there a case for a new method c.factor as follows?  Does something
> similar exist already?  Is there a better way to write the function?
> 
> > c.factor = function(x,y)
> {
>     newlevels = union(levels(x),levels(y))
>     m = match(levels(y), newlevels)
>     ans = c(unclass(x),m[unclass(y)])
>     levels(ans) = newlevels
>     class(ans) = "factor"
>     ans
> }
> > c(x,y)
>  [1] a b c d e d e f g h
> Levels: a b c d e f g h
> > as.integer(c(x,y))
>  [1] 1 2 3 4 5 4 5 6 7 8
> >
> 
> Regards,
> Matthew

I'll defer to others as to whether or not there is a basis for c.factor,
however:

c.factor <- function(...)
{
  args <- list(...)

  # this could be optional
  if (!all(sapply(args, is.factor)))
   stop("All arguments must be factors")

  factor(unlist(lapply(args, function(x) as.character(x))))
}


x <- factor(letters[1:5])
y <- factor(letters[4:8])
z <- factor(letters[9:14])

> x
[1] a b c d e
Levels: a b c d e

> y
[1] d e f g h
Levels: d e f g h

> z
[1] i j k l m n
Levels: i j k l m n


> c(x, y)
 [1] a b c d e d e f g h
Levels: a b c d e f g h


> c(x, y, z)
 [1] a b c d e d e f g h i j k l m n
Levels: a b c d e f g h i j k l m n


> c(x, 1:5)
Error in c.factor(x, 1:5) : All arguments must be factors


HTH,

Marc Schwartz



[Rd] c.factor
Marc Schwartz