r - R函数根据单位值分配固定资源
问题描述
我正在尝试在 R 中创建一个函数,以根据这些单位提供的值分配固定数量的单位。我设置了以下示例数据框。
fruit <- c("apple","orange","bannana","cherry")
units_of_mass <- c(9, 11, 16, 7)
health_pts <- c(5, 3, 6, 1)
diet_plan <- data.frame(fruit, units_of_mass, health_pts)
total_units_desired <- 32
所以我想做的是根据分配给每个水果的健康点分配所需的总单位,从最高健康点开始。
我尝试使用 dplyr 但卡住了
fruit_detail <- diet_plan %>%
arrange(fruit, health_pts) %>%
mutate(
cum_units = cumsum(units_of_mass) - units_of_mass,
can_allocate = total_units_desired - cum_units,
allocated = ifelse(can_allocate <= 0, 0, ifelse(can_allocate >=
cum_units, cum_units))
)
执行此操作的简单方法是按生命值排列并减去单位,直到用完 total_units_desired,如下所示:
## iterate on allocations
diet_plan <- setDT(diet_plan)
max <- max(diet_plan$health_pts)
allocation_1 <- subset(diet_plan, health_pts == max)
allocation_1[, units_allocated := ifelse(total_units_desired >
units_of_mass, units_of_mass, total_units_desired)]
remaining_units <- ifelse(total_units_desired - allocation_1$units_allocated
> 0, total_units_desired - allocation_1$units_allocated,
0)
diet_plan <- subset(diet_plan, health_pts < max)
max <- max(diet_plan$health_pts)
allocation_2 <- subset(diet_plan, health_pts == max)
allocation_2[, units_allocated := ifelse(remaining_units > units_of_mass,
units_of_mass, remaining_units)]
remaining_units <- ifelse(remaining_units - allocation_2$units_allocated >
0, remaining_units - allocation_2$units_allocated, 0)
diet_plan <- subset(diet_plan, health_pts < max)
max <- max(diet_plan$health_pts)
allocation_3 <- subset(diet_plan, health_pts == max)
allocation_3[, units_allocated := ifelse(remaining_units > units_of_mass,
units_of_mass, remaining_units)]
remaining_units <- ifelse(remaining_units - allocation_3$units_allocated >
0, remaining_units - allocation_3$units_allocated, 0)
diet_plan <- subset(diet_plan, health_pts < max)
max <- max(diet_plan$health_pts)
allocation_4 <- subset(diet_plan, health_pts == max)
allocation_4[, units_allocated := ifelse(remaining_units > units_of_mass,
units_of_mass, remaining_units)]
result <- rbind(allocation_1, allocation_2, allocation_3, allocation_4)
fruit units_of_mass health_pts units_allocated
bannana 16 6 16
apple 9 5 9
orange 11 3 7
cherry 7 1 0
解决方案
您提出问题的方式,我们可以按 排序health_pts
,然后找到 的累积总和,如果我们取该项目和它上面的所有项目units_of_mass
,这就是总和。units_allocated
然后我们可以filter
只拿那些不会让我们超过限制的物品total_units_desired
。
然后,剩余的行可以分配最大数量的单元:
diet_plan_sum %>%
arrange(desc(health_pts)) %>% # Sort by health_pts
mutate(cum_sum = cumsum(units_of_mass)) %>% # Calculate total cumulative units
filter(cum_sum < total_units_desired) %>% # Drop items over allocation limit
mutate(units_allocated = units_of_mass) %>% # For remaining rows, allocate max
select(-cum_sum) # Drop cum_sum variable
fruit units_of_mass health_pts units_allocated
1 bannana 16 6 16
2 apple 9 5 9
如果您想分配剩余的单位,我们可以对上述内容进行一些更改:
首先,我们找到超过阈值的第一行:这是唯一具有部分值的行。然后我们可以将它的units_allocated
值设置为total - the proceeding row's value
,也就是余数。
对于每隔一行,我们检查累积和是否大于阈值:如果是,则设置units_allocated
为 0,如果不是,则设置units_allocated
为units_of_mass
:
diet_plan_sum %>%
arrange(desc(health_pts)) %>%
mutate(cum_sum = cumsum(units_of_mass),
# Find the first row where we go over the threshold, set it to remainder
units_allocated = if_else(cum_sum > total_units_desired & lag(cum_sum) < total_units_desired,
total_units_desired - lag(cum_sum),
if_else(cum_sum > total_units_desired,
0,
units_of_mass))) %>%
select(-cum_sum) # Drop cum_sum variable
fruit units_of_mass health_pts units_allocated
1 bannana 16 6 16
2 apple 9 5 9
3 orange 11 3 7
4 cherry 7 1 0
推荐阅读
- jquery - 模态不显示按钮
- c++ - 重载运算符 == 和多态性的好习惯?
- python - Numba 和二维 numpy 数组列表
- java - 将 Solrj 与基本身份验证一起使用时,出现错误“原因:java.net.SocketException:连接重置”
- html - Django Html页面渲染项目循环
- c# - EventAggregator 如何注册事件和订阅者并通知所有订阅者事件触发?
- apache-spark - ¿ MultilayerPerceptronClassifier - Spark - mllib 中的 maxIter 参数是什么?
- android - 如何在 actionBar 但在 kotlin 中实现计数器
- c# - 打开 ID 连接 MVC 5
- c# - 如何从 SQL 查询中提取参数名称