My understanding is that R will not make copies of lists if there is only one reference to the object. However, I've encountered a case where R does make copies, even though (I think) there should be only one reference to the object. I hope that someone could shed some light on why this is happening.
I'll start with a simple example. Below, x is a list with one element, and changing that element doesn't result in a copy. (We know this because nothing is printed when we do the assignment after the tracemem call.) This is as expected. x <- list(1) tracemem(x) # [1] "<0x1149e08f8>" x[[1]] <- 2 # (No output) Similarly, modifying a list contained in a list doesn't result in a copy: e <- list(x = list(1)) tracemem(e$x) # [1] "<0x11b3a4b38>" e$x[[1]] <- 2 # (No output) However, modifying a list contained in an environment *does* result in a copy -- tracemem prints out some info when we do the assignment: e <- new.env(parent = emptyenv()) e$x <- list(1) tracemem(e$x) # [1] "<0x1148c1708>" e$x[[1]] <- 2 # tracemem[0x1148c1708 -> 0x11b2fc1b8]: This is surprising to me. Why is a copy made in this case? It also results in slower performance for these situations. The most that I've been able to figure out is that it probably has something to do with how the $ operator works with environments (but not with lists). If you do the same operations without the $ operator, by evaluating code in environment e, then no copy is made: e <- new.env(parent = globalenv()) eval(quote({ x <- list(1) tracemem(x) x[[1]] <- 2 }), envir = e) # (No output) I'd appreciate it if someone could shed light on this. And if it's a bug, that would be good to know too. -Winston ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel