首页 > 解决方案 > 如何根据存储在 tibble 中的数据执行未知数量的函数调用/“管道”?

问题描述

我将尝试使这个示例尽可能可重现和明确。

完全重现代码,您需要以下软件包...

library(tidyverse)
library(ompr)
library(ompr.roi)
library(ROI)
library(ROI.plugin.glpk)

而且,您需要创建以下“虚拟”数据集...

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)
  )

我的目标是使用 OMPR 包(混合线性规划)基于方程和一些边界/约束来反解一组未知因素,这些边界/约束取决于存储在“dummy_data”小标题中的数据。我设法快速使用 OMPR 包通过“手动输入”来自虚拟数据的所有必要信息来获得以下示例。以下是第一个类别 (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"))

现在,目标是为每个“类别”(即 A05、A15 和任何其他潜在的 Axx)创建相同的模型,而不仅仅是如上所示的 A01。我可以轻松创建“model2”和“model3”,然后手动输入所有数字。删除 A05 的“l”变量,然后为 A15 添加一个新的“o”变量(具有自己的特定边界)。

然而,这并不整洁,需要大量的手工工作,并且随着类别/变量数量的增加,它很快变得越来越不可持续。

是否有一种简洁的方式来逐步遍历虚拟数据集(可能在“类别”上使用 group_map),其中映射函数创建一个不同的模型(如上面手动演示的那样),但对于每个类别 - 基于唯一集的模型参数每个类别的数据集中存在的变量/数字?

我用 rlang/metaprogramming 标记了这个问题,因为我觉得我正在朝着“使用代码创建代码”来解决这个问题(使用 quo、eval 等)。然而,我在 R 编程的那部分完全天真/缺乏经验,我看好可能有一种更简单的方法来使用更少手动(和更整洁)的方法来解决这个问题!

感谢您提前提出的任何想法/帮助!

干杯,特洛伊

标签: rtidyversemetaprogrammingrlang

解决方案


推荐阅读