Передать список по ссылке в R и добавить в список - PullRequest
0 голосов
/ 26 апреля 2019

У меня есть функция в R, которая должна изменять список, добавляя в него новые элементы. Однако я действительно не хочу делать копию моего списка.

Я знаю, что это не простая задача в R, и я видел несколько минимальных примеров, использующих функцию eval.parent, но я не знаю, как они применимы к моему конкретному случаю.

Минимальный пример моей проблемы (не моей реальной функции) будет выглядеть как

L <- list(o1 = 1, o2 = 2, o3 = 3)
add_to_list <- function(L){
  n1 <- sum(unlist(L))
  n2 <- mean(unlist(L))
  L$n1 <- n1
  L$n2 <- n2
  return(L)
}
L <- add_to_list(L)

Если я прав, так как L изменяется, функция add_to_list сделает полную копию L, включая o1, o2 и o3, в этом примере? (Похоже, когда я смотрю на время вычисления моей фактической функции.)

Я бы хотел передать L по ссылке, так как это значительно повысило бы производительность моего кода. В моем реальном примере есть более трех объектов o1, o2 и o3, и некоторые из них действительно большие, и у меня также есть много кода перед финальными назначениями, поэтому я хочу, чтобы он был модульным как функция.

1 Ответ

1 голос
/ 27 апреля 2019

На самом деле, я думаю, что добавление в списки не делает глубоких копий предыдущих элементов, Вы можете проверить это с помощью базы R:

x <- 1:2
tracemem(x)

y <- 3:4

L <- list(x=x, y=y)

foo <- function(L) {
  L$z <- 5:6
  L
}

# no copy shown here
L <- foo(L)

# copy shown, x copied so that L$x stays unmodified
x[1L] <- 0L

Или с pryr:

library(pryr)

x <- 1:2
address(x)
[1] "0x26f5f344ba0"

foo <- function(L) {
  L$z <- 5:6
  L
}

L <- list(x=x)
L <- foo(L)
lx <- L$x

address(lx)
[1] "0x26f5f344ba0"
...