[R] use name (not values!) of a dataframe inside a funktion

William Dunlap wdunlap at tibco.com
Sat Feb 2 16:31:20 CET 2013


Another R-ish way of modifying an object with a function is to use
'replacement functions' (there must be other names, I'm not sure
what the standard is) that let you use syntax like
     someProperty(myData, ...) <- newProperty
To do this define a function called `someProperty<-` whose last argument
is named 'value' and which returns a modified version of its first argument.
When R sees the above syntax it does the equivalent of
   myData <- `someProperty<-`(myData, ..., value=newProperty)

E.g., 
> `useLog2Scale<-` <- function(dataframe, value) {
       if (value) dataframe[] <- lapply(dataframe, log2)
       else dataframe[] <- lapply(dataframe, function(x)2^x)
       dataframe
    }
> d <- data.frame(x=1:5, y=1/(1:5))
> useLog2Scale(d) <- TRUE
> d
         x         y
1 0.000000  0.000000
2 1.000000 -1.000000
3 1.584963 -1.584963
4 2.000000 -2.000000
5 2.321928 -2.321928
> useLog2Scale(d) <- FALSE
> d
  x         y
1 1 1.0000000
2 2 0.5000000
3 3 0.3333333
4 4 0.2500000
5 5 0.2000000

(Usually such a function is used to set a property in the data, such as a logScale
flag, that is used or queried later.)


Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of Greg Snow
> Sent: Friday, February 01, 2013 8:54 AM
> To: Winfried Moser
> Cc: r-help
> Subject: Re: [R] use name (not values!) of a dataframe inside a funktion
> 
> It is strongly discouraged in R to have functions that change data values
> in the global workspace (or any location other than their local
> environment).
> 
> The usual procedure in R is to have your function return a modified version
> of the object and the user then decides what to do with it.  They can
> assign it back to the same original object so that there is still only one
> copy and it has changed (but the user made that decision, not the
> programmer), or they can save it to a different name and not lose the
> original.
> 
> If you really want to change the original copy (and there are sometimes
> when the exception to the rule makes sense) then you can either use
> environments (which don't copy on modify) or use macros instead of
> functions.  Given your examples I would look at the macro approach first.
>  There is a 'defmacro' function in the 'gtools' package and the reference
> on the help page for 'defmacro' leads to the original R news (now R
> Journal) article describing the use of macros in R (definitely read this if
> you are considering this approach).
> 
> 
> On Thu, Jan 31, 2013 at 7:34 AM, Winfried Moser <winfried.moser at gmail.com>wrote:
> 
> > Dear Listers,
> >
> > can anyone help me, please.
> >
> > Since several days i try to figure out, how to assign values, vectors,
> > functions etc to variables with dynamically generated names inside of
> > functions.
> > Sometimes I succeed, but the success is rather arbitrary, it seems. up to
> > now i don't fully understand, why things like get, assign, <<- etc do
> > sometimes work, and sometimes not.
> >
> > here's one of my daily examples, i am stuck with: Example 1 does work, but
> > example 2 doesn't?
> > How kann i tell R, that i want it to expand the string "dfb" to "dfb[,2]"
> > inside the function.
> > In the end i want the function to change the second variable of the
> > dataframe dfb permanently to factor (not just inside the function).
> >
> > Thanks in advance!
> >
> > Winfried
> >
> >
> > Example 1:
> > dfa <- data.frame(a=c(1:4),b=c(1:4))
> > dfa[,2] <- factor(dfa[,2])
> > is.factor(dfa[,2])
> > >TRUE
> >
> > Example 2:
> > dfb <- data.frame(a=c(1:4),b=c(1:4))
> > f.fact <- function(x) {x[,2] <<- factor(x[,2])}
> > f.fact(dfb)
> > is.factor(dfb[,2])
> > >FALSE
> >
> >
> > PS: I tried a whole lot of other things like, ...
> > I really don't know where to keep on searching.
> >
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {get(x)[,2] <<- factor(get(x)[,2])}
> > f.fact("dfb")
> > is.factor(dfb[,2])
> > > "Object 'x' nicht gefunden
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {get(x[,2]) <<- factor(x[,2])}
> > f.fact(dfb)
> > is.factor(dfb[,2])
> > > "Object 'x' nicht gefunden
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {get(x)[,2] <<- factor(x[,2])}
> > f.fact(dfb)
> > is.factor(dfb[,2])
> > > "Object 'x' nicht gefunden
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {assign(x[,2], factor(x[,2]))}
> > f.fact(dfb)
> > is.factor(dfb[,2])
> > > Ungültiges erstes Argument
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {quote(x)[,2], factor(x[,2])}
> > f.fact(dfb)
> > is.factor(dfb[,2])
> > > Unerwartetes ','
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {
> > name <- paste0(quote(x),"[,2]")
> >  assign(name, factor(x[,2]))}
> > f.fact(dfb)
> > is.factor(dfb[,2])
> > > FALSE
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {
> > name <- paste0(get(x),"[,2]")
> > assign(name, factor(x[,2]))}
> > f.fact("dfb")
> > is.factor(dfb[,2])
> > > Falsche Anzahl von Dimensionen
> >
> > dfb <- data.frame(a=c(1,2,3,4),b=c(1,2,3,4))
> > f.fact <- function(x) {
> >  name <- paste0(x,"[,2]")
> > assign(name, factor(x[,2]))}
> > f.fact("dfb")
> > is.factor(dfb[,2])
> > > Falsche Anzahl von Dimensionen
> >
> > ächz ...
> >
> >         [[alternative HTML version deleted]]
> >
> >
> > ______________________________________________
> > R-help at r-project.org mailing list
> > 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.
> >
> >
> 
> 
> --
> Gregory (Greg) L. Snow Ph.D.
> 538280 at gmail.com
> 
> 	[[alternative HTML version deleted]]



More information about the R-help mailing list