[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.

See ?rapply for more information.

HTH,

Marc Schwartz



More information about the R-help mailing list