r - How to calculate "1+1" without using eval(parse(...? -


i have been looking quite while seems answer seems to use eval(parse(text="1+1")).

i have column in data frame, has list of strings such "1+1*6", "1*4/3" etc. wish compute these new column without using eval(parse( functions looking on 8 million rows.

it attempt answer question: given numbers 1:9 find solutions (a_b_c) / (d_e_f) = ghi, a:i numbers 1:9 (without repeating) , underscores 1 of 4 operators *, /, +,-, without repeating.

i created dataframe permutations of 1:9 , each of these calculated permutations of 4 operators.

require(gtools) x <- permutations(n = 9, r = 9, v = 1:9) y <- permutations(n = 4, r = 4, v = c("*", "/", "+", "-"))  for(i in 1:nrow(x)){   for(j in 1:nrow(y)){     math <- paste("(", x[i,1], y[j,1], x[i,2],y[j,2], x[i,3],")", "/", "(", x[i,4] ,y[j,3], x[i,5] ,y[j,4], x[i,6],")")     equals <- eval(parse(text=math))     sum <- as.numeric(paste0(x[i,7], x[i,8], x[i,9]))     if(sum==equals) {        print(c(i,j))     }   } } 

however takes far long, hence trying remove time consuming eval(parse(..

any appreciated. thanks!

freddie

vectorisation key

math <- apply(   y,   1,   function(j){     paste("(", x[, 1], j[1], x[, 2], j[2], x[, 3],")/(", x[, 4], j[3], x[, 5], j[4], x[, 6], ")")   } ) math <- apply(math, 2, paste, collapse = ",") math <- paste("c(", math, ")") equals <- sapply(parse(text = math), eval) sum <-matrix(x[, 7] * 100 + x[, 8] * 10 + x[, 9], nrow = nrow(x), ncol = nrow(y)) abs(sum - equals) < 1e-8 

let's see difference in speed is

require(gtools) x <- permutations(n = 9, r = 9, v = 1:9) y <- permutations(n = 4, r = 4, v = c("*", "/", "+", "-"))

x <- x[sample(nrow(x), 40), ] y <- y[sample(nrow(y), 20), ]  library(microbenchmark) microbenchmark(   loop = for(i in 1:nrow(x)){     for(j in 1:nrow(y)){       math <- paste("(", x[i,1], y[j,1], x[i,2],y[j,2], x[i,3],")", "/", "(", x[i,4] ,y[j,3], x[i,5] ,y[j,4], x[i,6],")")       equals <- eval(parse(text=math))       sum <- as.numeric(paste0(x[i,7], x[i,8], x[i,9]))       if(sum==equals) {          print(c(i,j))       }     }   },   vectorised = {     math <- apply(       y,       1,       function(j){         paste("(", x[, 1], j[1], x[, 2], j[2], x[, 3],")/(", x[, 4], j[3], x[, 5], j[4], x[, 6], ")")       }     )     math <- apply(math, 2, paste, collapse = ",")     math <- paste("c(", math, ")")     equals <- sapply(parse(text = math), eval)     sum <-matrix(x[, 7] * 100 + x[, 8] * 10 + x[, 9], nrow = nrow(x), ncol = nrow(y))     abs(sum - equals) < 1e-8   } ) 

the results:

unit: milliseconds        expr        min         lq       mean     median         uq       max neval cld        loop 158.666383 162.084918 167.477490 165.880665 170.258076 240.43746   100   b  vectorised   8.540623   8.966214   9.613615   9.142515   9.413117  17.88282   100   

Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -