I'll try to make this example as reproducible and explicit as possible.
To fully reproduce the code you'll need the following packages...
library(tidyverse)
library(ompr)
library(ompr.roi)
library(ROI)
library(ROI.plugin.glpk)
And, you'll need to create the following "dummy" set of data...
dummy_data <-
tibble(
category = c("A01", "A01", "A01", "A01", "A05", "A05", "A05", "A15", "A15", "A15", "A15"),
unknown = c("w", "b", "c", "l", "w", "b", "c", "w", "b", "c", "o"),
known = c(388610, 7760, 94970, 129931, 366472, 360477, 82212, 128021, 114379, 72185, 32807),
known_sum = c(1470189, 1470189, 1470189, 1470189, 1110194, 1110194, 1110194, 831287, 831287, 831287, 831287)
)
My goal is use the OMPR package (mixed linear programming) to back-solve for a set of unknown factors based on an equation and some bounds/constraints which depend on data stored in the "dummy_data" tibble. I managed to quickly use the OMPR package to get the following example working through "manually inputting" all the necessary information from the dummy data. Below is the example for only the first category (A01)...
model <-
MILPModel() %>%
add_variable(w, lb = 1.8, ub = 2.8, type = "continuous") %>%
add_variable(b, lb = 2.0, ub = 3.0, type = "continuous") %>%
add_variable(c, lb = 1.1, ub = 1.8, type = "continuous") %>%
add_variable(l, lb = 1.3, ub = 1.7, type = "continuous") %>%
set_objective(388610*w+ 7760*b+ 94970*c+ 129931*l, "min") %>%
add_constraint((388610*w+ 7760*b+ 94970*c+ 129931*l) == 1470189) %>%
solve_model(with_ROI(solver = "glpk"))
Now, the goal is to create an identical model for each "category" (i.e. A05, A15, and any other potential Axx), not just A01 as shown above. I could easily create 'model2' and 'model3' then manually input all the numbers. Removing the "l" variable for A05, and then adding a new "o" variable in for A15 (with its own specific bounds).
However, this doesn't feel tidy, it's a lot of manual work, and it quickly becomes increasingly unsustainable as the number of categories/variables increases.
Is there a tidy-way to step through the dummy data set (perhaps using a group_map on "category") where the mapping function creates a distinct model (as manually demonstrated above) but for every category - basing the model parameters on the unique set of variables/numbers present within the dataset for each category?
- Creating only the variables shown for that category (i.e. w, b, c, l for A01; w, b, c for A05; w, b, c, o for A15)
- Attribute the correct "known" numbers within the set_objective and add_constraint calls.
- Attribute the correct "known_sum" number to the end (RHS) of the add_constraint call.
I've tagged this question with rlang/metaprogramming because it feels to me that I'm moving towards "creating code using code" to solve this problem (using quo, eval, etc.). However, I am completely naïve/inexperienced in that part of R-programming, and I'm bullish that there might be a much simpler way to solve this problem using a less-manual (and more-tidy) methodology!
Appreciate any thought/assistance you might thrown my way in advance!
Cheers, Troy