# [R] substitute "x" for "pattern" in a list, while preservign list "structure". lapply, gsub, list...?

Marc Schwartz marc_schwartz at comcast.net
Wed May 16 18:37:23 CEST 2007

```On Wed, 2007-05-16 at 09:25 -0700, new ruser wrote:
> I am experimenting with some of the common r functions.
> I had a question re:using "gsub" (or some similar functions) on the
> contents of a list.
>
> I want to design a function that looks at "everything" contained din a
> list, and anytime it finds the text string "pattern" replace it with
> "x".  I also wish to preserve the "structure" of the original list.
> What is a good way to accomplish this?
>
> I tried :
>
> a = matrix(data=c(23,45,'red',78),nrow=2)
> b = c('red','green',1,2,3)
> d = data.frame( test1=c(223,445,'red',78,56) , test2=
> c('red',NA,NA,NA,NA) )
> e= list(a,b,d)
> list1 = list(a,b,d,e)
>
> list2 = lapply(list1,function(list)(gsub("red","green",list)))
>
> str(list1)
> str(list2)
>
> but the structue fo the list changed.

I suspect that you will need to use rapply(), which is a recursive
version of lapply().

For example:

> str(list1)
List of 4
\$ : chr [1:2, 1:2] "23" "45" "red" "78"
\$ : chr [1:5] "red" "green" "1" "2" ...
\$ :'data.frame':       5 obs. of  2 variables:
..\$ test1: Factor w/ 5 levels "223","445","56",..: 1 2 5 4 3
..\$ test2: Factor w/ 1 level "red": 1 NA NA NA NA
\$ :List of 3
..\$ : chr [1:2, 1:2] "23" "45" "red" "78"
..\$ : chr [1:5] "red" "green" "1" "2" ...
..\$ :'data.frame':    5 obs. of  2 variables:
.. ..\$ test1: Factor w/ 5 levels "223","445","56",..: 1 2 5 4 3
.. ..\$ test2: Factor w/ 1 level "red": 1 NA NA NA NA

list3 <- rapply(list1, function(x) gsub("red", "green", x),
how = "replace")

> str(list3)
List of 4
\$ : chr [1:2, 1:2] "23" "45" "green" "78"
\$ : chr [1:5] "green" "green" "1" "2" ...
\$ :List of 2
..\$ test1: chr [1:5] "223" "445" "green" "78" ...
..\$ test2: chr [1:5] "green" NA NA NA ...
\$ :List of 3
..\$ : chr [1:2, 1:2] "23" "45" "green" "78"
..\$ : chr [1:5] "green" "green" "1" "2" ...
..\$ :List of 2
.. ..\$ test1: chr [1:5] "223" "445" "green" "78" ...
.. ..\$ test2: chr [1:5] "green" NA NA NA ...

Note however, the impact of using gsub(), which is that factors are
coerced to characters. So consider what you want the end game to be.