I understood that data.table
is not copied when returned from a function. However, in this particular case it does get copied. Can one explain why?
dt1 <- data.table(a=1)
dt2 <- data.table(b=1)
dt3 <- data.table(c=1)
address(dt1); address(dt2); address(dt3)
[1] "000000005E20D990"
[1] "00000000052301E8"
[1] "000000001D622210"
l <- list(a=dt1, b=dt2, c=dt3)
address(l$a); address(l$b); address(l$c)
$[1] "000000005E20D990"
$[1] "00000000052301E8"
$[1] "000000001D622210"
f <- function(dt) {setnames(dt, toupper(names(dt)))}
l <- Map(f, l)
address(l$a); address(l$b); address(l$c)
$[1] "000000001945C7B0"
$[1] "0000000066858738"
$[1] "000000001B021038"
dt1
$ A
$1: 1
dt2
$ B
$1: 1
dt3
$ C
$1: 1
So it is the last line which is making the copy. However, the following does not make a copy.
address(dt1)
$[1] "000000005E20D990"
dt4 <- f(dt1)
address(dt4)
$[1] "000000005E20D990"
What am I missing?
Update
As everybody has pointed out, map
or mapply
is making a copy. lapply
works in the above case but my actual code needs multiple inputs in the function. My understanding was that all apply
functions use same code. But it does not seems to be the case.
Map
is a wrapper formapply
and I believe the copy happens inmapply
. – Exhibitionl<-lapply(l,f)
doesn't copy. I should add that the use ofMap
is pretty unusual, since there is just one argument and solapply
should be preferred. – KhachaturianC
code oflapply
there is the lineif (MAYBE_REFERENCED(tmp)) tmp = lazy_duplicate(tmp);
while inmapply
the line isif (MAYBE_REFERENCED(tmp)) tmp = duplicate(tmp);
. Could that be the cause? I'm not expert of R internals, so can't tell for sure. – KhachaturianMap
ormapply
if you have objects available in the parent frame. Then uselapply(seq_along(l), function(i) ...)
and subset objects used inmapply
usingi
iterator, sol[[i]]
in your example, potentially more asmapply
loops over multiple objects. – Molybdenitel <- Map(f, l)
to simplyMap(f, l)
, it seems to work fine. You rarely need to use the return value ofset*
functions. – Glumefuncdt<-f(dt1); address(funcdt)
shows same address. In other words, the problem isn't the function, it's theMap
– NicholsMap(f,l) works. But it still makes a copy of the data just not assign it to
l`. – Renatorenaud