[R] Avoiding deep copies
Luke Tierney
luke at nokomis.stat.umn.edu
Tue Oct 2 16:04:38 CEST 2001
On Tue, Oct 02, 2001 at 02:21:51PM +0200, Johann Petrak wrote:
> Is it correct that there is no way of avoiding deep copying
> of data structures? Or asked from a different perspective,
> is it true that there are no pointers? :)
> (not that I am a fan of pointer, they just let me
> decide when to do deep copy on my own when the
> memory manager doesnt do it for me :) )
>
> I was considering writing code in R that would need
> the internal representation of complex graph structures
> where several nodes in the graph point to the same
> huge array of data.
> Now, obviously one cannot just do something like
> attr(thenode,"mydatavec")<-thedatavec or
> thenode$mydatavec<-thedatavec
> since all the data in thedatavec will be copied
> with this assignment.
> Are there commonly accepted/used workarounds?
>
> Johann
>
There are two (useful) types of object that are passed by reference in
R: environments and external pointers. External pointers are useful
for managing data allocated at the C level. Environments are useful
for doing this sort of thing at the R level. For example, if you
define, say,
new.ref <- function(value = NULL) {
ref <- new.env()
assign("value", value, env = ref)
ref
}
ref.value <- function(ref) get("value", env = ref)
"ref.value<-" <- function(ref, value) {
assign("value", value, env = ref)
ref
}
then
r <- new.ref(<data that should not be copied>)
produces a reference object that will not be deep copied, and
s <- r
makes s another name for that reference, so that ref.value(s) <- <new value>
changes the value returned by ref.value(r):
> r <- new.ref(1)
> ref.value(r)
[1] 1
> s<-r
> ref.value(s) <- 2
> ref.value(s)
[1] 2
> ref.value(r)
[1] 2
A slightly fancier version would wrap the environment in a list and
attach a class to it, something like
new.ref <- function(value = NULL) {
ref <- list(env = new.env())
class(ref) <- "refObject"
assign("value", value, env = ref$env)
ref
}
is.refObject <- function(r) inherits(r, "refObject")
print.refObject <- function(r) cat("<reference>\n")
ref.value <- function(ref) {
if (! is.refObject(ref)) stop("not a refObject")
get("value", env = ref$env)
}
"ref.value<-" <- function(ref, value) {
if (! is.refObject(ref)) stop("not a refObject")
assign("value", value, env = ref$env)
ref
}
Then
> r <- new.ref(1)
> r
<reference>
> ref.value(3)
Error in ref.value(3) : not a refObject
We've talked about adding something like this off and on but have not
gotten around to it yet.
luke
--
Luke Tierney
University of Minnesota Phone: 612-625-7843
School of Statistics Fax: 612-624-8868
313 Ford Hall, 224 Church St. S.E. email: luke at stat.umn.edu
Minneapolis, MN 55455 USA WWW: http://www.stat.umn.edu
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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