Avoiding deep copies
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 _._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._