【问题标题】:Why does data.table get copied when returned from Map为什么从 Map 返回时 data.table 会被复制
【发布时间】:2016-01-21 12:44:04
【问题描述】:

我知道data.table 从函数返回时不会被复制。但是,在这种特殊情况下,它确实会被复制。谁能解释一下原因?

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

所以它是制作副本的最后一行。但是,以下内容不会复制。

address(dt1)
$[1] "000000005E20D990"
dt4 <- f(dt1)
address(dt4)
$[1] "000000005E20D990"

我错过了什么?

更新 正如大家所指出的,mapmapply 正在复制。 lapply 在上述情况下有效,但我的实际代码需要函数中的多个输入。我的理解是所有apply 函数都使用相同的代码。但似乎并非如此。

【问题讨论】:

  • Mapmapply 的包装器,我相信复制发生在 mapply 中。
  • 我在lapply 的源代码C 中注意到if (MAYBE_REFERENCED(tmp)) tmp = lazy_duplicate(tmp); 中有一行mapplyif (MAYBE_REFERENCED(tmp)) tmp = duplicate(tmp);。这可能是原因吗?我不是 R 内部的专家,所以不能确定。
  • 如果父框架中有可用的对象,您可以轻松避免使用Mapmapply。然后使用lapply(seq_along(l), function(i) ...)mapply 中使用的子集对象,使用i 迭代器,因此在您的示例中l[[i]] 可能更多,因为mapply 在多个对象上循环。
  • 如果我将l &lt;- Map(f, l) 切换为简单的Map(f, l),它似乎工作正常。您很少需要使用set* 函数的返回值。
  • 您应该改写问题,因为funcdt&lt;-f(dt1); address(funcdt) 显示相同的地址。换句话说,问题不在于功能,而在于Map

标签: r data.table mapply


【解决方案1】:

正如大家所指出的,Mapmapply 正在复制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-09
    • 2015-08-10
    • 2022-06-14
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多