Skip to contents

Define economic profit values for feasible planning unit–action pairs and store them in a profit table.

Profit is stored separately from ecological effects. In particular, profit is not the same as ecological benefit or loss as represented in add_effects. This separation allows the package to distinguish economic returns from ecological consequences when building objectives, constraints, and reporting summaries.

Usage

add_profit(x, profit = NULL)

Arguments

x

A Problem object created with create_problem. It must already contain feasible actions and an action catalogue; run add_actions first.

profit

Profit specification. One of:

  • NULL: profit is set to 0 for all feasible (pu, action) pairs,

  • a numeric scalar: recycled to all feasible pairs,

  • a named numeric vector: names are action ids and values define action-level profit,

  • a data.frame(action, profit) defining action-level profit,

  • a data.frame(pu, action, profit) defining pair-specific profit.

Value

An updated Problem object with a stored profit table created or replaced. The stored table contains columns pu, action, profit, internal_pu, and internal_action, and includes only rows with non-zero profit.

Details

When to use add_profit().

Use this function when economic returns, penalties, or other action-specific financial values are part of the planning problem. Typical downstream uses include objectives such as add_objective_max_profit and add_objective_max_net_profit.

Let \(\mathcal{I}\) denote the set of planning units and \(\mathcal{A}\) the set of actions. Let \(\mathcal{D} \subseteq \mathcal{I} \times \mathcal{A}\) denote the set of feasible planning unit–action pairs currently stored in the problem.

This function assigns to each feasible pair \((i,a) \in \mathcal{D}\) a numeric profit value \(\pi_{ia} \in \mathbb{R}\) and stores the result in a profit table.

Thus, the stored table can be interpreted as a mapping $$ \pi : \mathcal{D} \to \mathbb{R}, $$ where \(\pi_{ia}\) represents the economic return associated with selecting action \(a\) in planning unit \(i\).

Profit values may be positive, zero, or negative. Positive values represent gains or revenues, zero represents no net profit contribution, and negative values can be used to encode penalties or net economic losses.

The stored table contains:

  • pu: external planning-unit id,

  • action: action id,

  • profit: numeric profit value,

  • internal_pu: internal planning-unit index,

  • internal_action: internal action index.

Supported input formats

The profit argument may be specified in several ways:

  • NULL: assign profit 0 to all feasible (pu, action) pairs,

  • a numeric scalar: assign the same profit value to all feasible pairs,

  • a named numeric vector: names are action ids, assigning one global profit value per action,

  • a data.frame(action, profit): assign one global profit value per action,

  • a data.frame(pu, action, profit): assign pair-specific profit values.

When action-level profit is supplied, the same profit value is assigned to all feasible planning units for that action. When pair-specific profit is supplied, only the listed (pu, action) pairs receive explicit values; unmatched feasible pairs are interpreted as zero-profit pairs.

Storage behaviour

This function stores only rows with non-zero profit values. Feasible pairs whose final profit is zero are omitted from the stored profit table. Missing values produced during matching or joins are treated as zero before this filtering step. Therefore, the resulting table is a sparse representation of economic returns over the feasible decision space.

Data-only behaviour

This function is purely data-oriented. It does not build or modify the optimization model, and it does not change feasibility. It simply assigns profit values to rows already present in the feasible action table.

In particular:

  • it does not add new feasible (pu, action) pairs,

  • it does not remove infeasible pairs,

  • it does not apply solver-side filtering such as dropping locked-out decisions,

  • it does not modify ecological effect tables.

Any such filtering is expected to occur later when model-ready tables are prepared, typically during the build stage invoked by solve().

Use in optimization

Profit values stored by this function can later be used in objectives such as add_objective_max_profit or add_objective_max_net_profit, in derived budget expressions, or in reporting and summary functions.

For example, if \(x_{ia} \in \{0,1\}\) denotes whether action \(a\) is selected in planning unit \(i\), then a profit-maximization objective typically takes the form $$ \max \sum_{(i,a) \in \mathcal{D}} \pi_{ia} x_{ia}. $$

Examples

# Load a complete simulated planning problem.
example_data <- load_sim_multiaction()

p <- create_problem(
  pu = example_data$planning_units,
  features = example_data$features,
  dist_features = example_data$dist_features,
  cost = "cost"
) |>
  add_actions(
    example_data$actions,
    cost = example_data$action_costs
  )

# 1) Constant profit for every feasible (pu, action)
p1 <- add_profit(p, profit = 10)
p1$data$dist_profit
#>     pu  action profit internal_pu internal_action
#> 1    1 protect     10           1               1
#> 65   1 restore     10           1               2
#> 2    2 protect     10           2               1
#> 66   2 restore     10           2               2
#> 3    3 protect     10           3               1
#> 67   3 restore     10           3               2
#> 4    4 protect     10           4               1
#> 68   4 restore     10           4               2
#> 5    5 protect     10           5               1
#> 69   5 restore     10           5               2
#> 6    6 protect     10           6               1
#> 70   6 restore     10           6               2
#> 7    7 protect     10           7               1
#> 71   7 restore     10           7               2
#> 8    8 protect     10           8               1
#> 72   8 restore     10           8               2
#> 9    9 protect     10           9               1
#> 73   9 restore     10           9               2
#> 10  10 protect     10          10               1
#> 74  10 restore     10          10               2
#> 11  11 protect     10          11               1
#> 75  11 restore     10          11               2
#> 12  12 protect     10          12               1
#> 76  12 restore     10          12               2
#> 13  13 protect     10          13               1
#> 77  13 restore     10          13               2
#> 14  14 protect     10          14               1
#> 78  14 restore     10          14               2
#> 15  15 protect     10          15               1
#> 79  15 restore     10          15               2
#> 16  16 protect     10          16               1
#> 80  16 restore     10          16               2
#> 17  17 protect     10          17               1
#> 81  17 restore     10          17               2
#> 18  18 protect     10          18               1
#> 82  18 restore     10          18               2
#> 19  19 protect     10          19               1
#> 83  19 restore     10          19               2
#> 20  20 protect     10          20               1
#> 84  20 restore     10          20               2
#> 21  21 protect     10          21               1
#> 85  21 restore     10          21               2
#> 22  22 protect     10          22               1
#> 86  22 restore     10          22               2
#> 23  23 protect     10          23               1
#> 87  23 restore     10          23               2
#> 24  24 protect     10          24               1
#> 88  24 restore     10          24               2
#> 25  25 protect     10          25               1
#> 89  25 restore     10          25               2
#> 26  26 protect     10          26               1
#> 90  26 restore     10          26               2
#> 27  27 protect     10          27               1
#> 91  27 restore     10          27               2
#> 28  28 protect     10          28               1
#> 92  28 restore     10          28               2
#> 29  29 protect     10          29               1
#> 93  29 restore     10          29               2
#> 30  30 protect     10          30               1
#> 94  30 restore     10          30               2
#> 31  31 protect     10          31               1
#> 95  31 restore     10          31               2
#> 32  32 protect     10          32               1
#> 96  32 restore     10          32               2
#> 33  33 protect     10          33               1
#> 97  33 restore     10          33               2
#> 34  34 protect     10          34               1
#> 98  34 restore     10          34               2
#> 35  35 protect     10          35               1
#> 99  35 restore     10          35               2
#> 36  36 protect     10          36               1
#> 100 36 restore     10          36               2
#> 37  37 protect     10          37               1
#> 101 37 restore     10          37               2
#> 38  38 protect     10          38               1
#> 102 38 restore     10          38               2
#> 39  39 protect     10          39               1
#> 103 39 restore     10          39               2
#> 40  40 protect     10          40               1
#> 104 40 restore     10          40               2
#> 41  41 protect     10          41               1
#> 105 41 restore     10          41               2
#> 42  42 protect     10          42               1
#> 106 42 restore     10          42               2
#> 43  43 protect     10          43               1
#> 107 43 restore     10          43               2
#> 44  44 protect     10          44               1
#> 108 44 restore     10          44               2
#> 45  45 protect     10          45               1
#> 109 45 restore     10          45               2
#> 46  46 protect     10          46               1
#> 110 46 restore     10          46               2
#> 47  47 protect     10          47               1
#> 111 47 restore     10          47               2
#> 48  48 protect     10          48               1
#> 112 48 restore     10          48               2
#> 49  49 protect     10          49               1
#> 113 49 restore     10          49               2
#> 50  50 protect     10          50               1
#> 114 50 restore     10          50               2
#> 51  51 protect     10          51               1
#> 115 51 restore     10          51               2
#> 52  52 protect     10          52               1
#> 116 52 restore     10          52               2
#> 53  53 protect     10          53               1
#> 117 53 restore     10          53               2
#> 54  54 protect     10          54               1
#> 118 54 restore     10          54               2
#> 55  55 protect     10          55               1
#> 119 55 restore     10          55               2
#> 56  56 protect     10          56               1
#> 120 56 restore     10          56               2
#> 57  57 protect     10          57               1
#> 121 57 restore     10          57               2
#> 58  58 protect     10          58               1
#> 122 58 restore     10          58               2
#> 59  59 protect     10          59               1
#> 123 59 restore     10          59               2
#> 60  60 protect     10          60               1
#> 124 60 restore     10          60               2
#> 61  61 protect     10          61               1
#> 125 61 restore     10          61               2
#> 62  62 protect     10          62               1
#> 126 62 restore     10          62               2
#> 63  63 protect     10          63               1
#> 127 63 restore     10          63               2
#> 64  64 protect     10          64               1
#> 128 64 restore     10          64               2

# 2) Profit per action using a named vector
pr <- c(protect = 50, restore = -5)
p2 <- add_profit(p, profit = pr)
p2$data$dist_profit
#>     pu  action profit internal_pu internal_action
#> 1    1 protect     50           1               1
#> 65   1 restore     -5           1               2
#> 2    2 protect     50           2               1
#> 66   2 restore     -5           2               2
#> 3    3 protect     50           3               1
#> 67   3 restore     -5           3               2
#> 4    4 protect     50           4               1
#> 68   4 restore     -5           4               2
#> 5    5 protect     50           5               1
#> 69   5 restore     -5           5               2
#> 6    6 protect     50           6               1
#> 70   6 restore     -5           6               2
#> 7    7 protect     50           7               1
#> 71   7 restore     -5           7               2
#> 8    8 protect     50           8               1
#> 72   8 restore     -5           8               2
#> 9    9 protect     50           9               1
#> 73   9 restore     -5           9               2
#> 10  10 protect     50          10               1
#> 74  10 restore     -5          10               2
#> 11  11 protect     50          11               1
#> 75  11 restore     -5          11               2
#> 12  12 protect     50          12               1
#> 76  12 restore     -5          12               2
#> 13  13 protect     50          13               1
#> 77  13 restore     -5          13               2
#> 14  14 protect     50          14               1
#> 78  14 restore     -5          14               2
#> 15  15 protect     50          15               1
#> 79  15 restore     -5          15               2
#> 16  16 protect     50          16               1
#> 80  16 restore     -5          16               2
#> 17  17 protect     50          17               1
#> 81  17 restore     -5          17               2
#> 18  18 protect     50          18               1
#> 82  18 restore     -5          18               2
#> 19  19 protect     50          19               1
#> 83  19 restore     -5          19               2
#> 20  20 protect     50          20               1
#> 84  20 restore     -5          20               2
#> 21  21 protect     50          21               1
#> 85  21 restore     -5          21               2
#> 22  22 protect     50          22               1
#> 86  22 restore     -5          22               2
#> 23  23 protect     50          23               1
#> 87  23 restore     -5          23               2
#> 24  24 protect     50          24               1
#> 88  24 restore     -5          24               2
#> 25  25 protect     50          25               1
#> 89  25 restore     -5          25               2
#> 26  26 protect     50          26               1
#> 90  26 restore     -5          26               2
#> 27  27 protect     50          27               1
#> 91  27 restore     -5          27               2
#> 28  28 protect     50          28               1
#> 92  28 restore     -5          28               2
#> 29  29 protect     50          29               1
#> 93  29 restore     -5          29               2
#> 30  30 protect     50          30               1
#> 94  30 restore     -5          30               2
#> 31  31 protect     50          31               1
#> 95  31 restore     -5          31               2
#> 32  32 protect     50          32               1
#> 96  32 restore     -5          32               2
#> 33  33 protect     50          33               1
#> 97  33 restore     -5          33               2
#> 34  34 protect     50          34               1
#> 98  34 restore     -5          34               2
#> 35  35 protect     50          35               1
#> 99  35 restore     -5          35               2
#> 36  36 protect     50          36               1
#> 100 36 restore     -5          36               2
#> 37  37 protect     50          37               1
#> 101 37 restore     -5          37               2
#> 38  38 protect     50          38               1
#> 102 38 restore     -5          38               2
#> 39  39 protect     50          39               1
#> 103 39 restore     -5          39               2
#> 40  40 protect     50          40               1
#> 104 40 restore     -5          40               2
#> 41  41 protect     50          41               1
#> 105 41 restore     -5          41               2
#> 42  42 protect     50          42               1
#> 106 42 restore     -5          42               2
#> 43  43 protect     50          43               1
#> 107 43 restore     -5          43               2
#> 44  44 protect     50          44               1
#> 108 44 restore     -5          44               2
#> 45  45 protect     50          45               1
#> 109 45 restore     -5          45               2
#> 46  46 protect     50          46               1
#> 110 46 restore     -5          46               2
#> 47  47 protect     50          47               1
#> 111 47 restore     -5          47               2
#> 48  48 protect     50          48               1
#> 112 48 restore     -5          48               2
#> 49  49 protect     50          49               1
#> 113 49 restore     -5          49               2
#> 50  50 protect     50          50               1
#> 114 50 restore     -5          50               2
#> 51  51 protect     50          51               1
#> 115 51 restore     -5          51               2
#> 52  52 protect     50          52               1
#> 116 52 restore     -5          52               2
#> 53  53 protect     50          53               1
#> 117 53 restore     -5          53               2
#> 54  54 protect     50          54               1
#> 118 54 restore     -5          54               2
#> 55  55 protect     50          55               1
#> 119 55 restore     -5          55               2
#> 56  56 protect     50          56               1
#> 120 56 restore     -5          56               2
#> 57  57 protect     50          57               1
#> 121 57 restore     -5          57               2
#> 58  58 protect     50          58               1
#> 122 58 restore     -5          58               2
#> 59  59 protect     50          59               1
#> 123 59 restore     -5          59               2
#> 60  60 protect     50          60               1
#> 124 60 restore     -5          60               2
#> 61  61 protect     50          61               1
#> 125 61 restore     -5          61               2
#> 62  62 protect     50          62               1
#> 126 62 restore     -5          62               2
#> 63  63 protect     50          63               1
#> 127 63 restore     -5          63               2
#> 64  64 protect     50          64               1
#> 128 64 restore     -5          64               2

# 3) Profit per action using a data frame
pr_df <- data.frame(
  action = c("protect", "restore"),
  profit = c(40, 15)
)
p3 <- add_profit(p, profit = pr_df)
p3$data$dist_profit
#>     pu  action profit internal_pu internal_action
#> 1    1 protect     40           1               1
#> 2    1 restore     15           1               2
#> 3    2 protect     40           2               1
#> 4    2 restore     15           2               2
#> 5    3 protect     40           3               1
#> 6    3 restore     15           3               2
#> 7    4 protect     40           4               1
#> 8    4 restore     15           4               2
#> 9    5 protect     40           5               1
#> 10   5 restore     15           5               2
#> 11   6 protect     40           6               1
#> 12   6 restore     15           6               2
#> 13   7 protect     40           7               1
#> 14   7 restore     15           7               2
#> 15   8 protect     40           8               1
#> 16   8 restore     15           8               2
#> 17   9 protect     40           9               1
#> 18   9 restore     15           9               2
#> 19  10 protect     40          10               1
#> 20  10 restore     15          10               2
#> 21  11 protect     40          11               1
#> 22  11 restore     15          11               2
#> 23  12 protect     40          12               1
#> 24  12 restore     15          12               2
#> 25  13 protect     40          13               1
#> 26  13 restore     15          13               2
#> 27  14 protect     40          14               1
#> 28  14 restore     15          14               2
#> 29  15 protect     40          15               1
#> 30  15 restore     15          15               2
#> 31  16 protect     40          16               1
#> 32  16 restore     15          16               2
#> 33  17 protect     40          17               1
#> 34  17 restore     15          17               2
#> 35  18 protect     40          18               1
#> 36  18 restore     15          18               2
#> 37  19 protect     40          19               1
#> 38  19 restore     15          19               2
#> 39  20 protect     40          20               1
#> 40  20 restore     15          20               2
#> 41  21 protect     40          21               1
#> 42  21 restore     15          21               2
#> 43  22 protect     40          22               1
#> 44  22 restore     15          22               2
#> 45  23 protect     40          23               1
#> 46  23 restore     15          23               2
#> 47  24 protect     40          24               1
#> 48  24 restore     15          24               2
#> 49  25 protect     40          25               1
#> 50  25 restore     15          25               2
#> 51  26 protect     40          26               1
#> 52  26 restore     15          26               2
#> 53  27 protect     40          27               1
#> 54  27 restore     15          27               2
#> 55  28 protect     40          28               1
#> 56  28 restore     15          28               2
#> 57  29 protect     40          29               1
#> 58  29 restore     15          29               2
#> 59  30 protect     40          30               1
#> 60  30 restore     15          30               2
#> 61  31 protect     40          31               1
#> 62  31 restore     15          31               2
#> 63  32 protect     40          32               1
#> 64  32 restore     15          32               2
#> 65  33 protect     40          33               1
#> 66  33 restore     15          33               2
#> 67  34 protect     40          34               1
#> 68  34 restore     15          34               2
#> 69  35 protect     40          35               1
#> 70  35 restore     15          35               2
#> 71  36 protect     40          36               1
#> 72  36 restore     15          36               2
#> 73  37 protect     40          37               1
#> 74  37 restore     15          37               2
#> 75  38 protect     40          38               1
#> 76  38 restore     15          38               2
#> 77  39 protect     40          39               1
#> 78  39 restore     15          39               2
#> 79  40 protect     40          40               1
#> 80  40 restore     15          40               2
#> 81  41 protect     40          41               1
#> 82  41 restore     15          41               2
#> 83  42 protect     40          42               1
#> 84  42 restore     15          42               2
#> 85  43 protect     40          43               1
#> 86  43 restore     15          43               2
#> 87  44 protect     40          44               1
#> 88  44 restore     15          44               2
#> 89  45 protect     40          45               1
#> 90  45 restore     15          45               2
#> 91  46 protect     40          46               1
#> 92  46 restore     15          46               2
#> 93  47 protect     40          47               1
#> 94  47 restore     15          47               2
#> 95  48 protect     40          48               1
#> 96  48 restore     15          48               2
#> 97  49 protect     40          49               1
#> 98  49 restore     15          49               2
#> 99  50 protect     40          50               1
#> 100 50 restore     15          50               2
#> 101 51 protect     40          51               1
#> 102 51 restore     15          51               2
#> 103 52 protect     40          52               1
#> 104 52 restore     15          52               2
#> 105 53 protect     40          53               1
#> 106 53 restore     15          53               2
#> 107 54 protect     40          54               1
#> 108 54 restore     15          54               2
#> 109 55 protect     40          55               1
#> 110 55 restore     15          55               2
#> 111 56 protect     40          56               1
#> 112 56 restore     15          56               2
#> 113 57 protect     40          57               1
#> 114 57 restore     15          57               2
#> 115 58 protect     40          58               1
#> 116 58 restore     15          58               2
#> 117 59 protect     40          59               1
#> 118 59 restore     15          59               2
#> 119 60 protect     40          60               1
#> 120 60 restore     15          60               2
#> 121 61 protect     40          61               1
#> 122 61 restore     15          61               2
#> 123 62 protect     40          62               1
#> 124 62 restore     15          62               2
#> 125 63 protect     40          63               1
#> 126 63 restore     15          63               2
#> 127 64 protect     40          64               1
#> 128 64 restore     15          64               2

# 4) Profit per (pu, action) pair
pr_pair <- data.frame(
  pu = c(1, 2, 3),
  action = c("protect", "protect", "restore"),
  profit = c(100, 80, 30)
)
p4 <- add_profit(p, profit = pr_pair)
p4$data$dist_profit
#>   pu  action profit internal_pu internal_action
#> 1  1 protect    100           1               1
#> 3  2 protect     80           2               1
#> 6  3 restore     30           3               2