[R] correction to the previously asked question (about mergin g factors)

Liaw, Andy andy_liaw at merck.com
Thu Feb 5 22:32:43 CET 2004


First of all, I do not understand why conversion to characters are not
allowed.  That's what Sundar's solution is doing implicitly (but more
elegantly).

Here's a test of all three.  See the function definitions below.

> f1 <- factor(sample(letters[1:3], 1e4, replace=TRUE))
> f2 <- factor(sample(letters[3:5], 1e4, replace=TRUE))
> f3 <- factor(sample(letters[5:7], 1e4, replace=TRUE))
> 
> system.time(for (i in 1:1e2) mf <- mergeFac(f1, f2, f3))
[1] 4.54 0.00 4.73   NA   NA
> system.time(for (i in 1:1e2) mf2 <- mergeFac2(f1, f2, f3))
[1] 3.95 0.01 4.11   NA   NA
> system.time(for (i in 1:1e2) mf3 <- mergeFac3(f1, f2, f3))
[1] 3.61 0.00 3.76   NA   NA
> all(mf == mf2)
[1] TRUE
> all(mf == mf3)
[1] TRUE

First, my attempt at generalizing Spencer's suggestion:

mergeFac <- function(...) {
  l <- list(...)
  len <- sapply(l, length)
  lev <- unique(unlist(lapply(l, levels)))
  ans <- factor(rep(lev[1], sum(len)), levels=lev)
  idx.end <- cumsum(len)
  idx.start <- c(1, idx.end[-length(len)] + 1)
  for (i in seq(along=l)) {
    ans[idx.start[i]:idx.end[i]] <- l[[i]]
  }
  ans
}

Then explicit coercion to characters:

mergeFac2 <- function(...) {
  l <- list(...)
  factor(unlist(lapply(l, as.character)))
}

Then Sundar's solution:
mergeFac3 <- function(...) {
  l <- list(...)
  factor(do.call("c", lapply(l, function(x) levels(x)[x])))
}

Cheers,
Andy


> From: Sundar Dorai-Raj
> 
> How about simply
> 
> F1 <- factor(c("b", "a"))
> F2 <- factor(c("c", "b"))
> F3 <- factor(c(levels(F1)[F1], levels(F2)[F2]))
> 
> -sundar
> 
> Spencer Graves wrote:
> 
> >      What about the following:
> >  > F1 <- factor(c("b", "a"))
> >  > F2 <- factor(c("c", "b"))
> >  > k1 <- length(F1)
> >  > k2 <- length(F2)
> >  > F12.lvls <- unique(c(levels(F1), levels(F2)))
> >  > F. <- factor(rep(F12.lvls[1], k1+k1), levels=F12.lvls)
> >  > F.[1:k1] <- F1
> >  > F.[-(1:k1)] <- F2
> >  > F.
> > [1] b a c b
> > Levels: a b c
> > 
> >      This saves converting the factors to characters, which 
> might save 
> > computer time at the expense of your time.      hope this 
> helps.      
> > spencer graves
> > 
> > Svetlana Eden wrote:
> > 
> >> I have two factors l1, l2, and I'd like to merge them.
> >>
> >> (Remark:       The factors can not be converted to charaters)
> >>
> >> Function c() does not give me the result I want:
> >>
> >>
> >>  
> >>
> >>> l1 = factor(c('aaaa', 'bbbb'))
> >>> l2 = factor(c('ccc', 'dd'))
> >>> lMerge = factor(c(l1, l2))
> >>> lMerge
> >>>   
> >>
> >> [1] 1 2 1 2
> >> Levels: 1 2
> >>  
> >>
> >> I'd like to merge l1 and l2 and to get lMerge 
> >> ----------------------------------------------
> >>
> >> [1] aaaa bbbb ccc dd
> >> Levels: aaaa bbbb ccc dd
> >>
> >> instead of ----------
> >>
> >> [1] 1 2 1 2
> >> Levels: 1 2
> >>  
> >>
> >>
> >> How should I do that without converting the factors back 
> to strings.
> >> -------------------------------------------------------------------
> >>
> >>  
> >>
> > 
> > ______________________________________________
> > R-help at stat.math.ethz.ch mailing list
> > https://www.stat.math.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide! 
> > http://www.R-project.org/posting-guide.html
> 
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! 
> http://www.R-project.org/posting-guide.html
> 
> 


------------------------------------------------------------------------------
Notice:  This e-mail message, together with any attachments,...{{dropped}}




More information about the R-help mailing list