[19039] in s-news-athena

home help back first fref pref prev next nref lref last post

[S] Re: Summary: Adding a level to a factor.

daemon@ATHENA.MIT.EDU (=?iso-8859-1?Q?"G=E9rald_Jean"?=)
Wed Aug 25 10:15:16 1999

From: =?iso-8859-1?Q?"G=E9rald_Jean"?= <Gerald.Jean@spgdag.ca>
To: s-news@wubios.wustl.edu
Message-Id: <852567D8.0049753F.00@mail.spgdag.com>
Date: Wed, 25 Aug 1999 10:11:17 -0400
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit


Hello everyone,

it seems that my little question about adding levels to a factor generated
more trafic than anticipated!

I must first thank Brian Ripley, although the other solutions worked, his
avoid transforming first to
character and back to factor and is more elegant in my opinion.  I ended up
 writing a little function,
using the relevant code from "na.tree.replace", where I can pass as
argument the desired name for the
NA's factor.  The function also test if the input factor is indeed a factor
 and if it has any NA's.
What I didn't like about "na.tree.replace" was 1) you couldn't specify a
name for the new NA level,
2) it would abort when the input data frame had continuous variables, which
 is almost always the case,
with the data I work with anyway.  Of course with a little work
na.tree.replace could be modified to
accomodate both situations!  You'll find my little function at the end of
this mail.

But I was curious and tested the method recommended by prof. Ripley using
"na.tree.replace" directly,
it didn't work for me!  Maybe prof. Ripley can point out what I am doing
wrong, if I am doing anything
wrong.

# No NA's in this first test.

> length(ttt.no.NA)
[1] 17693
> is.factor(ttt.no.NA)
[1] T
> sum(is.na(ttt.no.NA))
[1] 0
> ttt.no.NA.tree _ na.tree.replace(as.data.frame(ttt.no.NA))$ttt.no.NA
> is.factor(ttt.no.NA.tree)
[1] F
> length(ttt.no.NA.tree)
[1] 0
> ttt.no.NA.tree
NULL

# Hence when no NA's are present "na.tree.replace" returns NULL.
# Now with NA's.

 length(ttt.with.NA)
[1] 17693
> is.factor(ttt.with.NA)
[1] T
> sum(is.na(ttt.with.NA))
[1] 471
> ttt.with.NA.tree _
na.tree.replace(as.data.frame(ttt.with.NA))$ttt.with.NA
> is.factor(ttt.with.NA.tree)
[1] F
> length(ttt.with.NA.tree)
[1] 0
> ttt.with.NA.tree
NULL

# Again when NA's are present "na.tree.replace" returns NULL?  I must be
doing something wrong?

# Same two exemples with the little function.

> is.factor(ttt.no.NA)
[1] T
> sum(is.na(ttt.no.NA))
[1] 0
> ttt.no.NA.factor_factor.na.replace(ttt.no.NA, 'Missing')

      No NA's in ttt.no.NA

> is.factor(ttt.no.NA.factor)
[1] T
> all.equal(ttt.no.NA, ttt.no.NA.factor)
[1] T

# When there is no NA's "factor.na.replace" returns the input vector.

# Now with NA's.

> is.factor(ttt.with.NA)
[1] T
> sum(is.na(ttt.with.NA))
[1] 471
> levels(ttt.with.NA)
[1] " 0=Moins d'un an" " 1= >= 1 et < 2 " " 2= >= 2 et < 3 " " 3= >= 3 et <
 4 "
[5] " 4= >= 4 et < 5 " " 5=Plus de 5 ans"
> ttt.with.NA.factor_factor.na.replace(ttt.with.NA, 'Missing')
> is.factor(ttt.with.NA.factor)
[1] T
> sum(is.na(ttt.with.NA.factor))
[1] 0
> levels(ttt.with.NA.factor)
[1] " 0=Moins d'un an" " 1= >= 1 et < 2 " " 2= >= 2 et < 3 " " 3= >= 3 et <
 4 "
[5] " 4= >= 4 et < 5 " " 5=Plus de 5 ans" "Missing"

# No more NA's and NA's replaced by "Missing".

Now the little function:

"factor.na.replace" <- function (x, value)
{
# Author  : Mathsoft, from "na.tree.replace", modified by Gerald Jean
# Date    : August 1999
# Purpose : Will replace NA's in factor "x" by "value".
# Parameters :
#  x     : a factor variable.
#  value : the value by which to replace the NA's in "x".

   if (!is.factor(x))
     {cat(paste('\n\t',deparse(substitute(x)), ' is not a factor.',
                sep = ''), sep = '\n')
      return(x)
     }
   pos       <- is.na(x)
   if (sum(pos) == 0)
     {cat(paste('\n\t', ' No NA\'s in ', deparse(substitute(x)),
                sep = ''), sep = '\n')
      return(x)
     }
   cl        <- class(x)
   class(x)  <- NULL
   lev       <- c(attr(x, "levels"), value)
   x[pos]    <- length(lev)
   levels(x) <- lev
   class(x)  <- cl
   x
}

Thanks again to everyone who responded,

Gérald Jean
Analyste-conseil (statistiques), Actuariat
télephone            : (418) 835-8839
télecopieur          : (418) 835-5865
courrier électronique: gerald.jean@spgdag.ca

"In God we trust all others must bring data"


-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu.  To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message:  unsubscribe s-news

home help back first fref pref prev next nref lref last post