[R] Make sure a data frame has been "fun through" a function

William Dunlap
Tue, 21 Feb 2017 16:52:06 -0000

Stray attributes on data.frames may or may not survive some simple
operations on the data.frame.  E.g.,

> d <- data.frame(X=1:5, Y=log(1:5),
G=factor(rep(c("a","b"),c(2,3))))
> attr(d, "checked") <- TRUE
> wasChecked <- function(x) isTRUE(attr(x, "checked"))
> wasChecked(d)
[1] TRUE
> wasChecked(d[1:4,]) # select some rows
[1] TRUE
> wasChecked(d[,1:2]) # select some columns
[1] FALSE
> d[1,1] <- 10 # change a single value
> wasChecked(d)
[1] TRUE
> d$NewColumn <- 11:15 # add a column
> wasChecked(d)
[1] TRUE

I don't know if this would be an issue in your case.  If it is, you
could subclass "data.frame" and define methods so that the operations
of interest preserve or remove the attribute in the way that you
desire.

Bill Dunlap
TIBCO Software
wdunlap tibco.com


On Tue, Feb 21, 2017 at 8:30 AM, Charles C. Berry <ccberry at ucsd.edu>
wrote:
> On Tue, 21 Feb 2017, stephen sefick wrote:
>
>> Sorry for not being clear. I have never used S3 methods before. Below
is
>> some R code that sketches out my idea. Is this a sensible solution?
>>
>
> Sure. See comments (untested) inline.
>
> Chuck
>
>> test_data <- data.frame(a=1:10, b=1:10, c=1:10)
>>
>> functionA <- function(x, impossible_genotype){
>>    ##some data processing
>>    y <- x
>>
>>    ##return S3 to be able to use impossible genotype later
>>    class(y) <- append(class(y),"genotypes")
>
>
>      class(y) <- c("genotypes",class(y))
>
>>
>>    attr(y, "impossible_genotype") <- impossible_genotype
>>
>>    return(y)
>> }
>>
>> test_data_genotypes <- functionA(test_data,
impossible_genotype="Ref")
>>
>> functionB <- function(x){
>>    ##stop if pre-processed with functionA
>>    if(sum(class(x)=="genotypes")!=1){stop("Need to
pre-process data with
>> functionA")}
>
>
>     if(!(inherits("genotypes")){
>         stop("Need to pre-process data with functionA")}
>
>
> or in functionA you could skip the class()<- and just set the
> "impossible_genotypes" attribute to FALSE when there are none
such.
>
> Then here test
>
>      if (is.null(attr(x,"impossible_genotypes"))){
>                 stop("Need to pre-process data with functionA")
>         } else {
>                 return(alleles)
>         }
>
>
>>
>>    ##use this later in functionB to
>>    impossible_genotype <- attributes(x)$impossible_genotype
>
>
>      impossible_genotype <- attr(x,"impossible_genotype")
>>
>>
>>    alleles <- c("Ref", "Alt")
>>
>>    coded_genotype <- alleles[alleles!=impossible_genotype]
>
>
>      maybe `!is.element(alleles,impossible_genotype)' is safer than
`!='
>
>>
>>
>>
>>    return(coded_genotype)
>> }
>>
>> ##stop if not pre-processed with functionA
>> functionB(test_data)
>>
>> ##processed with functionA
>> functionB(test_data_genotypes)
>>
>
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.