[R] [., multiple inheritance, and R 1.6

Frank E Harrell Jr fharrell at virginia.edu
Fri Oct 25 14:37:56 CEST 2002

Matt Nelson <MNelson at sequenom.com> reported a problem using the Hmisc library that did not occur with versions of R before 1.6.  I am running

platform i686-pc-linux-gnu
arch     i686
os       linux-gnu
system   i686, linux-gnu
major    1
minor    6.0
year     2002
month    10
day      01
language R

> library(Hmisc)
> g <- factor(sample(c('a','b'),100,TRUE))
> label(g) <- 'label for g'
> class(g)
[1] "labelled" "factor"
> d <- data.frame(g,y)
> d[d$g=='a',]

Error in NextMethod("[") : ..1 used in an incorrect context, no ... to look in
> traceback()
7: NextMethod("[")
6: "[.factor"(xj, i)
5: NextMethod("[")
4: "[.labelled"(xj, i)
3: xj[i]
2: "[.data.frame"(d, d$g == "a", )   # in package:base
1: d[d$g == "a", ]

The error occurs in [.labelled before [.factor (the one in Hmisc that overrides the builtin [.factor)) is invoked.  [.labelled is defined as

function(x, ...) {
  atr <- attributes(x)
  x <- NextMethod("[")
  attr(x, "label") <- atr$label
  if(length(atr$units)) attr(x,'units') <- atr$units
    attr(x,'class') <- c("labelled", attr(x,'class'))

One confusing point is that the cat(2) is not executed although traceback() indicates that it was.  So the problem may instead be in [.factor.  Before I pursue this further, does anyone know of a change in 1.6 that would cause problems with [. and multiple inheritance?  The problem does not occur when subsetting the vector (g[g=='a']), so [.data.frame is also involved:

[.factor in Hmisc is defined as

function(x, ..., drop=TRUE) {
  atx <- attributes(x)
  nam <- atx$names
  atx$levels <- atx$names <- NULL
  y <- as.integer(x)[...]
  ln <- length(nam)
  nam <- if(ln) nam[...] else NULL
  opt <- .Options$drop.factor.levels
  if(!length(opt)) opt <- .Options$drop.unused.levels  # 18Mar01
  if(drop && (!missing(drop) || (length(opt)==0 || opt))) {
        oldClass(y) <- NULL
        j <- sort(unique(y))
        y[] <- match(y,j)
        levels(y) <- levels(x)[j]
  } else if(length(y)) levels(y) <- levels(x) ##only needed for length 0 subscripts
  attributes(y) <- c(attributes(y), atx, if(ln)list(names=nam))

Thanks for any help,


P.S.  As always, if an option existed to carry along attributes such as 'label', 'units', 'comment', no additional [. functions such as [.labelled would need to be defined by users. 
Frank E Harrell Jr              Prof. of Biostatistics & Statistics
Div. of Biostatistics & Epidem. Dept. of Health Evaluation Sciences
U. Virginia School of Medicine  http://hesweb1.med.virginia.edu/biostat
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch

More information about the R-help mailing list