[R] how to update a value in a list with lapply

Henric Winell nilsson.henric at gmail.com
Mon May 11 15:41:47 CEST 2015


On 2015-05-10 21:14, David Winsemius wrote:

> On May 10, 2015, at 6:11 AM, ce wrote:
>
>>
>> yes indeed :
>>
>> foo <- lapply(foo, function(x) if(x[1] == 1 ) {x[2] <- 0; x
>> }else{x} )
>>
>> would work. But if the list is too long, would it be time consuming
>> rather than just updating elements that meet the if condition?
>
> Any change to an object will require copying the entire object. That
> is the computing model that R uses. If you had presented a
> modification strategy that used logical or numeric indexing to effect
> only targeted nodes of a list, it still would have ended up copying
> the whole object.

This used to be true, but is no longer the case (from R-3.1.0 if my
memory serves me right).  Consider the following example.

> lst <- list(c(1L, 2L), 3.0)
> lst
[[1]]
[1] 1 2

[[2]]
[1] 3

>
> .Internal(inspect(lst))
@1fecce8 19 VECSXP g1c2 [MARK,NAM(1)] (len=2, tl=0)
   @26996a8 13 INTSXP g1c1 [MARK] (len=2, tl=0) 1,2
   @2699648 14 REALSXP g1c1 [MARK,NAM(2)] (len=1, tl=0) 3

Note the memory addresses (the ones starting with @).  Now, let's modify
the first list element:

> lst[[1]][1] <- 4L
> .Internal(inspect(lst))
@1fecce8 19 VECSXP g1c2 [MARK,NAM(1)] (len=2, tl=0)
   @26996a8 13 INTSXP g1c1 [MARK] (len=2, tl=0) 4,2
   @2699648 14 REALSXP g1c1 [MARK,NAM(2)] (len=1, tl=0) 3

As you can see, 'lst' changed but the memory address is still the same. 
  However, if we assign a double instead of an integer in the same 
position, copying must take place since the internal representation is 
changed:

> lst[[1]][1] <- 4.0
> .Internal(inspect(lst))
@1fecce8 19 VECSXP g1c2 [MARK,NAM(1)] (len=2, tl=0)
   @12685a0 14 REALSXP g0c2 [] (len=2, tl=0) 4,2
   @2699648 14 REALSXP g1c1 [MARK,NAM(2)] (len=1, tl=0) 3

But note that *only* the address of the first list element changed. 
This list itself and the second list element remain at the same 
addresses as before.


Henric Winell



>
> The data.table package was invented in large part to get around that
> design concern.
>



More information about the R-help mailing list