以比嵌套的ifelse块更好的方式处理条件

时间:2013-08-08 02:28:58

标签: r if-statement conditional

我正在尝试编写一些代码来分析我公司的保险计划产品......但它们很复杂! PPO计划很简单,但是高免赔额的健康计划很复杂,因为他们为家庭计划引入了“分割”免赔额最大限额(个人和全部)。它的工作原理如下:

  • 一旦个人遇到个人免赔额,他/她就会被90%
  • 保险
  • 一旦计划中剩余的1个以上的人满足免赔额,整个家庭的保险金额为90%
  • 个人不能仅以医疗费用
  • 来满足家庭免赔额

我想为我的家庭成员(其中有四个)提供费用,并输出每个计划的总费用。下面是可能的方案表,包含以下列代码:

  • ded_ind:一个人遇到个人免赔额吗?
  • ded_tot:达到的免赔额是多少?
  • oop_ind:个人最多达不到个人
  • oop_tot:是否已达到最大的口袋?
  • exp_ind =最高消费者的开支
  • exp_rem =剩余/其他/家庭成员(不是最高消费者)的费用
  • oop_max_ind =个人支付最高费用的费用水平(个人最多ded_ind + 0.1 * exp_ind =个人支付
  • oop_max_fam =与个人相同,但剩余家庭成员

表格:

| ded_ind | oop_ind | ded_rem | oop_rem | formula                                       
|---------+---------+---------+---------+---------------------------------------------------------------------------|
|       0 |       0 |       0 |       0 | exp_ind + exp_rem                                                         |
|       1 |       0 |       0 |       0 | ded_ind + 0.1 * (exp_ind - ded_ind) + exp_rem                             |
|       0 |       0 |       1 |       0 | exp_ind + ded_rem + 0.1 * (exp_rem - ded_rem)                             |
|       1 |       1 |       0 |       0 | oop_max_ind + exp_fam                                                     |
|       1 |       0 |       1 |       0 | ded_ind + 0.1 * (exp_ind - ded_ind) + ded_rem + 0.1 * (exp_rem - ded_rem) |
|       0 |       0 |       1 |       1 | oop_max_rem + exp_ind                                                     |
|       1 |       0 |       1 |       1 | ded_ind + 0.1 * (exp_ind - ded_ind) + oop_max_rem                         |
|       1 |       1 |       1 |       0 | oop_ind_max + ded_rem + 0.1 * (exp_rem - ded_rem)                         |
|       1 |       1 |       1 |       1 | oop_ind_max + oop_rem_max                                                 |

省略: 0 1 0 00 0 0 10 1 1 00 1 0 1不存在,如oop_ind和{{1如果未分别oop_remded_ind,则无法满足。

我当前的代码是一个有点大规模的ded_rem循环(不是代码,而是代码):

ifelse

在其他之后,总数大于家庭免赔额。我查看它是否由两个以上的人提供,并继续这样做。

我的问题,现在我已经给出了一些问题的背景知识:是否有更好的方法来管理这样的条件情况,而不是check if plan is ppo or hsa if hsa plan if exp_ind + exp_rem < ded_rem # didn't meet family deductible if exp_ind < ded_ind # individual deductible also not met cost = exp_ind + exp_rem else is exp_ind > oop_ind_max # ded_ind met, is oop_ind? ded_ind + 0.1 * (exp_ind - ded_ind) + exp_fam # didn't reach oop_max_ind else oop_max_ind + exp_fam # reached oop_max_ind else ... 循环,以便一次过滤掉它们?

代码最终看似多余,因为我们检查某些更高级别的条件(考虑满足ifelse或未满足ded_rem的表格......仍然需要检查ded_ind和{{ 1}}在两种情况下,代码都是相同的...只是位于oop_max_ind结构中的两个不同位置。)

这可以通过某种矩阵运算来完成吗?是否还有其他更聪明的方法来处理条件过滤?

非常感谢任何建议。


P.S。我正在使用R并将与ifelse创建一个交互式,以便其他员工可以为每个家庭成员输入最佳和最差情况,并通过点或条形图查看前面的计划。

2 个答案:

答案 0 :(得分:0)

基于结果转换为二进制值的建议给了我一个想法,这也帮助我学会了可以进行矢量化TRUE / FALSE检查(我猜这可能是显而易见的多)。

这是我目前的想法:

expenses将成为当年个人预测医疗费用的向量(三个人的例子):

expenses <- c(1500, 100, 400)

我们将exp_ind设置为最大值,并将exp_rem

的其余部分相加
exp_ind <- max(expenses)

# [1] index of which() for cases with multiple max values
exp_rem <- sum(expenses[-which(expenses == exp_ind)[1]])

对于任何给定的计划,我可以设置带有截止值的向量,例如:

  • 个人免赔额= 1000
  • 个人自掏腰包max = 2000(需要支付11k的费用才能到达)
  • family deductible = 2000
  • 家庭自掏腰包max = 4000(需要支付22k的费用才能到达那里)

设置这些值:

ded_ind <- 1000
oop_max_ind <- 11000
ded_tot <- 2000
oop_max_tot <- 22000

cutoffs <- c(ded_ind, oop_max_ind, ded_tot, oop_max_tot)

现在我们可以根据截止值检查输入费用:

result <- as.numeric(rep(c(exp_ind, exp_rem), each = 2) > cutoffs)

最后,转换为二进制文件:

result_bin <- sum(2^(seq_along(result) - 1) * result)

现在,我可以根据result_bin中的值设置可能结果的函数:

if(result_bin == 1) {cost <- ded_ind + 0.1 * (exp_ind - ded_ind) + exp_rem }

cost
[1] 1550

我们可以检查一下......

  • 高消费者将支付他的1000,然后10%的剩余500 = 1050
  • 其他会员未达到家庭免赔额并支付全额400 + 100 = 500
  • 总计:1550

我仍然需要创建results_bin值到相应函数的映射,但在我看来,进行矢量化检查并转换唯一二进制值比我的ifelse嵌套要好得多混乱。

我这样看:我必须设置变量并编写函数无论如何;这节省了我1)明确地写了所有的条件,2)我正在讨论的冗余问题,最终在ifelse结构中编写父分裂的相同“兄弟”分支,最后,3)代码远远,更容易被追随。

答案 1 :(得分:0)

由于这个问题不是很具体,这里有一个更简单的例子/答案:

# example data
test <- expand.grid(opt1=0:1,opt2=0:1)
# create a unique identifier to represent the binary variables
test$code <- with(allopts,paste(opt1,opt2,sep=""))
# create an input variable to be used in functions
test$var1 <- 1:4

#  opt1 opt2 code var1
#1    0    0   00    1
#2    1    0   10    2
#3    0    1   01    3
#4    1    1   11    4

根据二进制条件应用的各个函数,以及每个组合的预期结果:

var1 + 10    #code 00 - intended result =   11
var1 + 100   #code 10 - intended result =  102
var1 + 1000  #code 01 - intended result = 1003
var1 + var1  #code 11 - intended result =    8

使用ifelse组合进行计算:

test$result <- with(test,
  ifelse(code == "00", var1 + 10,
  ifelse(code == "10", var1 + 100,
  ifelse(code == "01", var1 + 1000,
  ifelse(code == "11", var1 + var1,
  NA
)))))

结果:

  opt1 opt2 code var1 result
1    0    0   00    1     11
2    1    0   10    2    102
3    0    1   01    3   1003
4    1    1   11    4      8