Search code examples
rreferencecopydeep-copyr6

Shallow and deep copy of R6 elements in a list


Here is a simple R6Class

C = R6::R6Class(
    "C",
    public = list(
        x = NULL,

        initialize = function(x)
        {
            self$x=x
        }
    )
)

By default the clone method takes deep=FALSE (and I would not know how to redefine clone to change that). I am dealing with lists of instances of class C. When copying these lists, I sometimes want to copy the C objects in it by reference and sometimes I want to deep copy them.

Here is an example of copy by reference

A = list(a1 = C$new(1), a2 = C$new(2))
B = A

print(B[["a1"]]$x) # [1]
A[["a1"]]$x = 4
print(B[["a1"]]$x) # [4]

I am struggling to deep copy the list though. I could do

A = list(a1 = C$new(1), a2 = C$new(2))
B = list(a1=A[["a1"]]$clone(deep=TRUE), a2=A[["a2"]]$clone(deep=TRUE))

print(B[["a1"]]$x) # [1]
A[["a1"]]$x = 4
print(B[["a1"]]$x) # [1]

However this technique is really not ideal as it is not I need to know the name of each element in the list. Is there some convenient way I could just do

B = copy_Cinstances_by_reference(A)

and

B = deep_copy_Cinstances(A)

?


Solution

  • You can just copy each element of the list one by one over a for loop. I suppose that might comes at a performance cost when dealing with large lists though and it is probably not the cleanest method.

    A = list(a1 = C$new(1), a2 = C$new(2))    
    
    B = list()
    for (name in names(A))
    {
        B[[name]] = A[[name]]$clone(deep=TRUE)
    }
    
    print(B[["a1"]]$x) # [1]
    A[["a1"]]$x = 4
    print(B[["a1"]]$x) # [1]