new ruser
2007-May-16 16:25 UTC
[R] substitute "x" for "pattern" in a list, while preservign list "structure". lapply, gsub, list...?
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. --------------------------------- Give spam the boot. Take control with tough spam protection [[alternative HTML version deleted]]
Marc Schwartz
2007-May-16 16:37 UTC
[R] substitute "x" for "pattern" in a list, while preservign list "structure". lapply, gsub, list...?
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
Gabor Grothendieck
2007-May-16 18:22 UTC
[R] substitute "x" for "pattern" in a list, while preservign list "structure". lapply, gsub, list...?
Here is a recursive function you could try. Here f has been defined only to convert character variables. Modify to suit. recurse <- function(x, f) { if (length(x) == 0) return(x) if (is.list(x)) for(i in seq_along(x)) x[[i]] <- recurse(x[[i]], f) else x <- f(x) x } f <- function(x) if (mode(x) == "character") gsub("red", "green", x) else x list4 <- recurse(list1, f) On 5/16/07, new ruser <newruser at yahoo.com> 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. > > > --------------------------------- > Give spam the boot. Take control with tough spam protection > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >