[R] replacement functions for subsets

William Dunlap wdunlap at tibco.com
Wed Jul 10 23:09:15 CEST 2013


If you define a function 'foo<-'  to replace a part of an object you need
to have a corresponding function 'foo' that extracts that same part.
If 'foo' does not exist or if 'foo' extracts something other than what 'foo<-'
alters, then nested replacements will not work.

The expression
   bar(foo(x)) <- newValue
is evaluated as
   tmp <- foo(x) # extract the part of x you want to alter
   bar(tmp) <- newValue # alter the extracted stuff
   foo(x) <- tmp # put the altered extracted stuff back where it came from
   # tmp is then discarded
('tmp' is chosen to be a name like '*tmp*'; you will see that in the traceback
after an error.)

Sometimes the 'extracted part' is not really a part of an object but something
more abstract, but the it is still true that foo<- and foo need to be paired.  E.g.,
  > twoTimes <- function(x) {
  +     cat("Calling twoTimes: x=", deparse(x), "\n")
  +     x * 2
  + }
  > `twoTimes<-` <- function(x, value) {
  +     cat("Calling twoTimes<-: x=", deparse(x), "\n")
  +     x[] <- value/2
  +     x
  + }
  > p <- 1:5
  > twoTimes(p)
  Calling twoTimes: x= 1:5 
  [1]  2  4  6  8 10
  > twoTimes(p)[1:2] <- c(100,102)
  Calling twoTimes: x= 1:5 
  Calling twoTimes<-: x= 1:5 
  > p
  [1] 50 51  3  4  5
  > 
  > p <- 1:5
  > twoTimes(p[1:2]) <- c(100,102)
  Calling twoTimes<-: x= 1:2 
  > p
  [1] 50 51  3  4  5
 
 
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 Harry Mamaysky
> Sent: Wednesday, July 10, 2013 1:23 PM
> To: Bert Gunter
> Cc: r-help at r-project.org
> Subject: Re: [R] replacement functions for subsets
> 
> So how would I get the following to work?
> 
> > aa<-1
> > aa
> [1] 1
> > 'foo<-' <- function(x,value) x<-value
> > foo(aa)<-1:10
> > aa
> [1]  1  2  3  4  5  6  7  8  9 10
> > # This doesn't work:
> > foo(aa)[4:5] <- c(101,102)
> Error in foo(aa)[4:5] <- c(101, 102) : could not find function "foo"
> > # What I would like to see is: aa becomes 1 2 3 101 102 6 7 8 9 10
> > # Is it possible to define such a function 'foo'?
> 
> 
> Sent from my iPhone
> 
> On Jul 10, 2013, at 4:10 PM, Bert Gunter <gunter.berton at gene.com> wrote:
> 
> I think the OP may perhaps want to define a method for "[<-" .
> 
> e.g. try:
> 
> methods("[<-")
> 
> If this is not it ... ??
> 
> Cheers,
> Bert
> 
> On Wed, Jul 10, 2013 at 12:51 PM, David Winsemius
> <dwinsemius at comcast.net> wrote:
> >
> > On Jul 10, 2013, at 12:17 PM, Harry Mamaysky wrote:
> >
> >> As I understand it rownames(aa) returns a copy of an attribute of aa. So changing the
> value of this vector should make the change to the copy of the row.names attribute. I
> would then have to set the original row.names equal to this copy to effect the change.
> >>
> >> So my question is why "rownames(aa)[2:4] <-" changes the original attribute rather
> than its copy?
> >
> > I'm not sure how you decide that was happening. Your first paragraph seemed correct:
> >
> > aa <- data.frame( a=1:10,b=101:110 )
> > str(aa)
> > attributes(aa)
> > dput(aa)
> > `rownames<-`
> >
> >> trace(`rownames<-`)
> >> rownames(aa)[2:4] <- c('row2','row3','row4')
> > trace: `rownames<-`(`*tmp*`, value = c("1", "row2", "row3", "row4",
> > "5", "6", "7", "8", "9", "10"))
> >
> > You can see that R first builds a full length vector with the second argumens to
> `rownames<-` fully expanded before doing the assignment to the 'row.names' attribute.
> >
> >>
> >> And the follow on question is whether it's possible to have "f(x)[2:4] <-" operate in the
> same way for some user defined replacement function f.
> >
> > Take a look at the code:
> >
> > `row.names<-.data.frame`
> >
> > --
> > David.
> >>
> >> Sent from my iPhone
> >>
> >> On Jul 10, 2013, at 3:05 PM, David Winsemius <dwinsemius at comcast.net> wrote:
> >>
> >>
> >> On Jul 10, 2013, at 11:47 AM, Harry Mamaysky wrote:
> >>
> >>> I know how to define replacement functions in R (i.e. ‘foo<-‘ <- function(x,value) x<-
> value, etc.), but how do you define replacement functions that operate on subsets of
> arrays (i.e. how do you pass an index into foo)?
> >>> For example, why does the following use of “rownames” work?
> >>
> >> `rownames` of a dataframe is a vector, so indexing with "[" and a single vector of
> indices is adequate. I cannot really tell what your conceptual "why"-difficulty might be.
> This is just assignment within a vector. That is not really a "replacement function
> operating on a subset of an array" since rownames are not values of the dataframe ....
> and it's not an "array". (Careful use of terms is needed here.)
> >>
> >>
> >>>
> >>>> aa <- data.frame( a=1:10,b=101:110 )
> >>>
> >>>> aa
> >>>
> >>> a   b
> >>>
> >>> 1   1 101
> >>>
> >>> 2   2 102
> >>>
> >>> 3   3 103
> >>>
> >>> 4   4 104
> >>>
> >>> 5   5 105
> >>>
> >>> 6   6 106
> >>>
> >>> 7   7 107
> >>>
> >>> 8   8 108
> >>>
> >>> 9   9 109
> >>>
> >>> 10 10 110
> >>>
> >>>> rownames(aa)[2:4] <- c('row2','row3','row4')
> >>>
> >>>> aa
> >>>
> >>>   a   b
> >>>
> >>> 1     1 101
> >>>
> >>> row2  2 102
> >>>
> >>> row3  3 103
> >>>
> >>> row4  4 104
> >>>
> >>> 5     5 105
> >>>
> >>> 6     6 106
> >>>
> >>> 7     7 107
> >>>
> >>> 8     8 108
> >>>
> >>> 9     9 109
> >>>
> >>> 10   10 110
> >>>
> >>>
> >>>
> >>>
> >>> Thanks,
> >>>
> >>> Harry
> >>>
> >>>
> >>>  [[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.
> >>
> >> David Winsemius
> >> Alameda, CA, USA
> >
> > David Winsemius
> > Alameda, CA, USA
> >
> > ______________________________________________
> > 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.
> 
> 
> 
> --
> 
> Bert Gunter
> Genentech Nonclinical Biostatistics
> 
> Internal Contact Info:
> Phone: 467-7374
> Website:
> http://pharmadevelopment.roche.com/index/pdb/pdb-functional-groups/pdb-
> biostatistics/pdb-ncb-home.htm
> 
> 	[[alternative HTML version deleted]]



More information about the R-help mailing list