r - Trying to avoid for loop with sapply (for gsub) -


trying avoid using for loop in following code utilizing sapply, if @ possible. solution loop works fine me, i'm trying learn more r , explore many methods possible.

objective: have vector i , 2 vectors sf (search for) , rp (replace). each i need loop on sf , replace rp match.

i  = c("1 6 5 4","7 4 3 1") sf = c("1","2","3") rp = c("one","two","three")  funn <- function(i) {   (j in seq_along(sf)) = gsub(sf[j],rp[j],i,fixed=t)   return(i) } print(funn(i)) 

result (correct):

[1] "one 6 5 4"     "7 4 3 one" 

i'd same, sapply

#trying avoid loop in fun #funn1 <- function(i) { #  = gsub(sf,rp,i,fixed=t) #  return(i) #} #print(sapply(i,funn1)) 

apparently, above commented code not work can first element of sf. first time using sapply, i'm not sure how convert "inner" implicit loop vectorized solution. (even statement - not possible) appreciated!

(i'm aware of mgsub not solution here. keep gsub)

edit: full code packages , belowoffered solutions , timing:

#timing library(microbenchmark) library(functional)   = rep(c("1 6 5 4","7 4 3 1"),10000) sf = rep(c("1","2","3"),100) rp = rep(c("one","two","three"),100)  #loop funn <- function(i) {   (j in seq_along(sf)) = gsub(sf[j],rp[j],i,fixed=t)   return(i) } t1 = proc.time() k = funn(i) t2 = proc.time()  #print(k)  print(microbenchmark(funn(i),times=10))  #mapply t3 = proc.time() mapply(function(u,v) i<<-gsub(u,v,i), sf, rp) t4 = proc.time()  #print(i)  print(microbenchmark(mapply(function(u,v) i<<-gsub(u,v,i), sf, rp),times=10))  #curry t5 = proc.time() reduce(compose, map(function(u,v) curry(gsub, pattern=u, replacement=v), sf, rp))(i) t6 = proc.time()  print(microbenchmark(reduce(compose, map(function(u,v) curry(gsub, pattern=u, replacement=v), sf, rp))(i), times=10))  #4th option n <- length(sf) sf <- setnames(sf,1:n) rp <- setnames(rp,1:n)  t7 = proc.time() reduce(function(x,j) gsub(sf[j],rp[j],x,fixed=true),c(list(i),as.list(1:n))) t8 = proc.time()  print(microbenchmark(reduce(function(x,j) gsub(sf[j],rp[j],x,fixed=true),c(list(i),as.list(1:n))),times=10))  #usual proc.time print(t2-t1) print(t4-t3) print(t6-t5) print(t8-t7) 

times:

unit: milliseconds     expr min  lq mean median  uq max neval  funn(i) 143 143  149    145 147 165    10 unit: seconds                                                expr min  lq mean median  uq max neval  mapply(function(u, v) <<- gsub(u, v, i), sf, rp) 4.1 4.2  4.4    4.3 4.4 4.9    10 unit: seconds                                                                                            expr min  lq mean median  uq max neval  reduce(compose, map(function(u, v) curry(gsub, pattern = u, replacement = v),      sf, rp))(i) 1.6 1.6  1.7    1.7 1.7 1.7    10 unit: milliseconds                                                                                       expr min  lq mean median  uq max neval  reduce(function(x, j) gsub(sf[j], rp[j], x, fixed = true), c(list(i),      as.list(1:n))) 141 144  147    145 146 162    10    user  system elapsed     0.15    0.00    0.15     user  system elapsed     4.49    0.03    4.52     user  system elapsed     1.68    0.02    1.68     user  system elapsed     0.19    0.00    0.18  

so, indeed in case for loop offers best timing , (in opinion) straightforward, simple, , possibly elegant. sticking loop.

thanks all. suggestions accepted , upvoted.

one approach - advantage conciseness not functional programming oriented - since has border effect in modifying i:

mapply(function(u,v) i<<-gsub(u,v,i), sf, rp) #> #[1] "one 6 5 4"     "7 4 3 one" 

or here pure functional programming approach:

library(functional) reduce(compose, map(function(u,v) curry(gsub, pattern=u, replacement=v), sf, rp))(i) #[1] "one 6 5 4"     "7 4 3 one" 

what map(function(u,v) curry(gsub, pattern=u, replacement=v), sf, rp) builds list of function respectively replace 1 one, 2 two, etc. these functions composed , applied i, giving desired result.


Comments

Popular posts from this blog

Email notification in google apps script -

c++ - Difference between pre and post decrement in recursive function argument -

javascript - IE11 incompatibility with jQuery's 'readonly'? -