The calculation of new variable using the equation and parameters provided in separate columns in R
I have a data frame with five columns, which are needed to calculate a new variable (y):
- variable x (numeric)
- equation 1 (character)
- parameter a for equation 1
- parameter b for equation 1
- parameter c for equation 1
data <- data.frame(
x = c(3,4,5),
equation = c("5*x + a * 2 - pi * b", "10*x + a - log(b)", "-x + a + c"),
a = c(1,4,8),
b = c(0.1,4,-8),
c =c(1.5,0.4,18),
y = c(NA, NA, NA),
y_expected = c(16.69, 42.61, 21.00))
Now, for each row separately, I would like to use the equation 1 and a, b and c parameters to calculate y (see the expected y values calculated manually). I have used the following code to do it, but the result is not correct. What happens here is that the y variable is calculate using the equation from column 3.
library(dplyr)
mutate(data, y = eval(parse(text=equation)))
x equation a b c y y_expected
1 3 5*x + a * 2 - pi * b 1 0.1 1.5 -0.5 16.69
2 4 10*x + a - log(b) 4 4.0 0.4 0.4 42.61
3 5 -x + a + c 8 -8.0 18.0 21.0 21.00
Warning message:
Problem with `mutate()` column `y`.
i `y = eval(parse(text = equation))`.
i NaNs produced
How can I fix this? I know I can achieve the solution using the for loop, but I am striking for more elegant solution.
list1 <- list()
for (i in 1:nrow(data)){
temp_df <- data[i, ]
temp_df <- mutate(temp_df, y = eval(parse(text=equation)))
list1[[i]] <- temp_df
}
do.call(rbind, list1)
x equation a b c y y_expected
1 3 5*x + a * 2 - pi * b 1 0.1 1.5 16.68584 16.69
2 4 10*x + a - log(b) 4 4.0 0.4 42.61371 42.61
3 5 -x + a + c 8 -8.0 18.0 21.00000 21.00
Solution 1:
dplyr::rowwise()
should do the trick...
library(dplyr)
data %>%
rowwise() %>%
mutate(y = eval(parse(text=equation)))
#> # A tibble: 3 x 7
#> # Rowwise:
#> x equation a b c y y_expected
#> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 3 5*x + a * 2 - pi * b 1 0.1 1.5 16.7 16.7
#> 2 4 10*x + a - log(b) 4 4 0.4 42.6 42.6
#> 3 5 -x + a + c 8 -8 18 21 21
Created on 2022-01-24 by the reprex package (v2.0.1)