1

I'm trying to convert strings from a column into formulas and output the result based on values I specify. For example:

Compo <- c("FE56", "FE58", "FE61", "YI68", "FE11")
Formula <- c("( FE13 / 0.06 ) * CE68", 
             "( ( CE01 + CE02 + CE03 ) / 100 ) * ( 393682 / 10000 )", 
             "FE12 / 0.06", 
             "CE68", 
             "FQ11")
table <- data.frame(Compo, Formula) 

FE13 <- 13
CE68 <- 20
CE01 <- 5
CE02 <- 15
CE03 <- 5.067
FE12 <- 35
FQ11 <-37

table$resultado <- parse(text = tabela$Formula)
table$results <- eval(tabela$resultado)

The output: enter image description here

But the column results only returns the value from the last formula, when it supposed to return the result from each formula.

Ben Bolker
  • 211,554
  • 25
  • 370
  • 453
Tagli94
  • 21
  • 2
  • Can you please edit your question to include your results in a textual format (i.e., not a screenshot/image)? – Ben Bolker May 18 '23 at 20:20

2 Answers2

1

I recommend to create a vectorized and customized function:

parse_string_formula <- function(formula){
  return(eval(parse(text = formula)))
}
parse_string_formula <- Vectorize(parse_string_formula)

table$final_result <- parse_string_formula(table$Formula)

  Compo                                               Formula       final_result
1  FE56                                ( FE13 / 0.06 ) * CE68 4333.3333333333339
2  FE58 ( ( CE01 + CE02 + CE03 ) / 100 ) * ( 393682 / 10000 )    9.8684266940000
3  FE61                                           FE12 / 0.06  583.3333333333334
4  YI68                                                  CE68   20.0000000000000
5  FE11                                                  FQ11   37.0000000000000
one
  • 3,121
  • 1
  • 4
  • 24
1

You can also do this with dplyr if you make the parameter values variables in the data. Sometimes people advise against the eval(), parse() combination, so this uses the tidy versions of these same concepts:

library(dplyr)
library(rlang)

Compo <- c("FE56", "FE58", "FE61", "YI68", "FE11")
Formula <- c("( FE13 / 0.06 ) * CE68", "( ( CE01 + CE02 + CE03 ) / 100 ) * ( 393682 / 10000 )", "FE12 / 0.06", "CE68", "FQ11")
table <- data.frame(Compo, Formula) 

params <- data.frame(
  FE13 =  13,
CE68 =  20,
CE01 =  5,
CE02 =  15,
CE03 =  5.067,
FE12 =  35,
FQ11 = 37)

table <- bind_cols(table, params)
table <- table %>% 
  rowwise() %>% 
  mutate(result = eval_tidy(parse_expr(Formula))) %>% 
  select(1,2,result)
table
#> # A tibble: 5 × 3
#> # Rowwise: 
#>   Compo Formula                                                result
#>   <chr> <chr>                                                   <dbl>
#> 1 FE56  ( FE13 / 0.06 ) * CE68                                4333.  
#> 2 FE58  ( ( CE01 + CE02 + CE03 ) / 100 ) * ( 393682 / 10000 )    9.87
#> 3 FE61  FE12 / 0.06                                            583.  
#> 4 YI68  CE68                                                    20   
#> 5 FE11  FQ11                                                    37

Created on 2023-05-18 with reprex v2.0.2

DaveArmstrong
  • 18,377
  • 2
  • 13
  • 25
  • I don't think the advice against using eval/parse is specific to the base R eval/parse. I gather it was more to do with not storing code as text strings in the first place, when there's often a better way to do it. Though for this particular question where that has already occurred, there's not a whole lot of alternatives. – thelatemail May 18 '23 at 21:31
  • @thelatemail - there are some other concerns [see here](https://stackoverflow.com/questions/13649979/what-specifically-are-the-dangers-of-evalparse), but I think you're right that if you get this far, there aren't many other options. – DaveArmstrong May 19 '23 at 15:07