From maechler at stat.math.ethz.ch  Tue Mar 21 10:17:35 2006
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Tue, 21 Mar 2006 10:17:35 +0100
Subject: [Rd] levels for list and data.frame
In-Reply-To: <441F2C49.8080703@gmail.com>
References: <441F2C49.8080703@gmail.com>
Message-ID: <17439.50351.172900.987055@stat.math.ethz.ch>

Hi Gregor,

before even considering methods for "list" and "data.frame",
can you explain why you think it is important for  levels() to
become a generic function at all?
For me, levels belong to factors (or then to contour plots, or
co-plots ) but exactly because level is a too generic word, it
seems to me to be problematic as a generic function.

How would describe the purpose of the levels() generic?

>>>>> "Gregor" == Gregor Gorjanc <gregor.gorjanc at gmail.com>
>>>>>     on Mon, 20 Mar 2006 23:27:21 +0100 writes:

    Gregor> oops, this does not pass R CMD check. I will have to read manuals a bit
    Gregor> more.

    Gregor> ...
    Gregor> * checking S3 generic/method consistency ... WARNING
    Gregor> levels:
    Gregor> function(x, ...)
    Gregor> levels.list:
    Gregor> function(x, drop)

    Gregor> levels:
    Gregor> function(x, ...)
    Gregor> levels.data.frame:
    Gregor> function(x, drop)
    Gregor> ...

    Gregor> Anyway, I would like to ask what is the "opinion" about writing methods
    Gregor> for classes as list and data.frame. Methods for this might not be as
    Gregor> simple as for numeric, character, factor and it would be nice that there
    Gregor> would be some guidelines for at least:
    Gregor> - what should be the "general" output i.e. list or something else - I
    Gregor> understand that it is hard to say in advance, but a common policy might
    Gregor> not hurt
    Gregor> - what to do if a method for a list or data.frame can not be applied to
    Gregor> each entry/column


    >> Hello!
    >> 
    >> Does R core find the following pacth usefull - I created methods for
    >> levels for list and data.frame, which can be usefull to get a list of
    >> levels for entries in a list or columns in a data.frame. Patch is
    >> attached and shown bellow example
    >> 
    >> # Example
    >>> tmp <- list()
    >>> tmp$a <- factor(letters[1:10])
    >>> tmp$b <- factor(letters[5:14])
    >>> tmp$c <- 1:10
    >>> tmp1 <- as.data.frame(tmp)
    >>> tmp2 <- list()
    >>> tmp2$"1" <- tmp
    >>> tmp2$"2" <- tmp1
    >>> str(tmp2)
    >> List of 2
    >> $ 1:List of 3
    >> ..$ a: Factor w/ 10 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10
    >> ..$ b: Factor w/ 10 levels "e","f","g","h",..: 1 2 3 4 5 6 7 8 9 10
    >> ..$ c: int [1:10] 1 2 3 4 5 6 7 8 9 10
    >> $ 2:`data.frame':      10 obs. of  3 variables:
    >> ..$ a: Factor w/ 10 levels "a","b","c","d",..: 1 2 3 4 5 6 7 8 9 10
    >> ..$ b: Factor w/ 10 levels "e","f","g","h",..: 1 2 3 4 5 6 7 8 9 10
    >> ..$ c: int [1:10] 1 2 3 4 5 6 7 8 9 10
    >> 
    >>> levels(tmp2)
    >> $"1"
    >> $"1"$a
    >> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
    >> 
    >> $"1"$b
    >> [1] "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
    >> 
    >> 
    >> $"2"
    >> $"2"$a
    >> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
    >> 
    >> $"2"$b
    >> [1] "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
    >> 
    >>> levels(tmp2, drop = FALSE)
    >> $"1"
    >> $"1"$a
    >> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
    >> 
    >> $"1"$b
    >> [1] "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
    >> 
    >> $"1"$c
    >> NULL
    >> 
    >> 
    >> $"2"
    >> $"2"$a
    >> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
    >> 
    >> $"2"$b
    >> [1] "e" "f" "g" "h" "i" "j" "k" "l" "m" "n"
    >> 
    >> $"2"$c
    >> NULL
    >> 
    >> ----------------------------------------------------------------------
    >> 
    >> $ svn diff factor.R
    >> Index: factor.R
    >> ===================================================================
    >> --- factor.R    (revision 37559)
    >> +++ factor.R    (working copy)
    >> @@ -25,7 +25,25 @@
    >> ## Help old S users:
    >> category <- function(...) .Defunct()
    >> 
    >> -levels <- function(x) attr(x, "levels")
    >> +levels <- function(x, ...) UseMethod("levels")
    >> +
    >> +levels.default <- function(x, ...) attr(x, "levels")
    >> +
    >> +levels.list <- function(x, drop = TRUE)
    >> +{
    >> +    tmp <- lapply(x, levels, drop = drop)
    >> +    if (drop) {
    >> +        tmp1 <- unlist(lapply(tmp, is.null))
    >> +        tmp <- tmp[!tmp1]
    >> +    }
    >> +    return(tmp)
    >> +}
    >> +
    >> +levels.data.frame <- function(x, ...)
    >> +{
    >> +    return(levels.list(x, ...))
    >> +}
    >> +
    >> nlevels <- function(x) length(levels(x))
    >> 
    >> "levels<-" <- function(x, value) UseMethod("levels<-")
    >> 

    Gregor> -- 
    Gregor> Lep pozdrav / With regards,
    Gregor> Gregor Gorjanc

    Gregor> ----------------------------------------------------------------------
    Gregor> University of Ljubljana     PhD student
    Gregor> Biotechnical Faculty
    Gregor> Zootechnical Department     URI: http://www.bfro.uni-lj.si/MR/ggorjan
    Gregor> Groblje 3                   mail: gregor.gorjanc <at> bfro.uni-lj.si

    Gregor> SI-1230 Domzale             tel: +386 (0)1 72 17 861
    Gregor> Slovenia, Europe            fax: +386 (0)1 72 17 888

    Gregor> ----------------------------------------------------------------------
    Gregor> "One must learn by doing the thing; for though you think you know it,
    Gregor> you have no certainty until you try." Sophocles ~ 450 B.C.

    Gregor> ______________________________________________
    Gregor> R-devel at r-project.org mailing list
    Gregor> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] levels for list and data.frame
Martin Maechler