我正在考虑一项潜在的政策变更,允许组织(OrgID
)在符合特定条件的情况下花费现有的补助金。数据是三列,这里是前六行:
OrgID Amount Group
1 1 5782457 Group1
2 2 2280221 Group3
3 3 3260741 Group4
4 4 3869420 Group1
5 5 3950578 Group1
6 6 2058883 Group2
这将每年发生一次,条件取决于组织所在的组(Group
)及其当前余额(Amount
)。具体地,
Group
=Group1
- 如果Amount
为500,000美元或更低,则所有资金都可用于支付 - 如果Amount
超过500,000美元,则可以花费50%的资金。
Group
=Group2
- 如果Amount
为$ 300,000或更低,则所有资金都可用于支付 - 如果Amount
超过$ 300,000,则可以花费30%的资金。
Group
=Group3
- 如果Amount
为100,000美元或更低,则所有资金都可用于支付 - 如果Amount
大于$ 100,000,则可以花费10%的资金。
Group
=Group4
- 在任何条件下都不能花钱。
我想知道未来五年每年剩余的总金额,所以我转向dplyr软件包并写了以下内容:
mydata <-
mydata %>%
mutate(ReleaseOne =
ifelse(Group == "Group1",
ifelse(Amount <= 500000, Amount,
round(Amount*0.50, 2)),
ifelse(Group == "Group2",
ifelse(Amount <= 300000, Amount,
round(Amount*0.30, 2)),
ifelse(Group == "Group3",
ifelse(Amount <= 100000, Amount,
round(Amount*0.10, 2)), 0)))) %>%
mutate(RemainOne =
Amount - ReleaseOne)
...
mydata <-
mydata %>%
mutate(ReleaseFive =
ifelse(Group == "Group1",
ifelse(RemainFour <= 500000, RemainFour,
round((RemainFour)*0.50, 2)),
ifelse(Group == "Group2",
ifelse(RemainFour <= 300000, RemainFour,
round((RemainFour)*0.30, 2)),
ifelse(Group == "Group3",
ifelse(RemainFour <= 100000, RemainFour,
round((RemainFour)*0.10, 2)), 0)))) %>%
mutate(RemainFive =
RemainFour - ReleaseFive)
因此,我只重复了相同的代码块五次,但每次我更改以&#34; Release&#34;开头的变量的名称。和&#34;保持&#34; (即RemaimOne
至RemainTwo
,ReleaseOne
至ReleaseTwo
等。)
这样做很好但是很乱。有没有办法使用自定义函数简化此操作,例如可能包括for
和while
循环?
此外,知道在第1,2和3组中的所有组织达到Amount = 0
之前将会有多少年是有价值的。但是,我知道如何做的唯一方法是不断重复上述内容,直到金额达到零。
数据名为mydata.txt,可以在this link的GitHub上找到。
答案 0 :(得分:1)
您可以创建一个单独的数据框以与 -
进行比较grp_data <- data.frame("Group" = c("Group1", "Group2", "Group3", "Group4"),
"threshold" = c(500000,300000,100000,0),
"percent" = c(0.5, 0.3, 0.1, 0))
mydata$allowed <- sapply(seq(nrow(mydata)), function(x)
{
ifelse(mydata[x, "Amount"] >=
grp_data[grp_data$Group == mydata[x, "Group"], "threshold"],
grp_data[grp_data$Group == mydata[x, "Group"], "percent"] * mydata[x, "Amount"],
mydata[x, "Amount"])
})
答案 1 :(得分:0)
这里有一个小功能应该可以解决问题 - 我也做了一些更通用的功能。它没有圆,但我确定你可以编辑它,如果你喜欢。
extrap = function(data,
threshhold = c(5e5, 3e5, 1e5, 0),
below = c(1, 1, 1, 1),
above = c(.5, .3, .1, 0),
n = 4) {
res = list()
x = data$Amount
g = as.numeric(data$Group)
for (i in 1:n) {
x = x * above[g] ^ (x > threshhold[g]) * below[g] ^ (x <= threshhold[g])
res[[i]] = x
}
names(res) = paste0("Release_", 1:n)
return(bind_cols(data, res))
}
在您在问题中分享的数据的head
上运行它:
extrap(dd)
# OrgID Amount Group Release_1 Release_2 Release_3 Release_4
# 1 1 5782457 Group1 2891228.5 1445614.25 722807.12 361403.56
# 2 2 2280221 Group3 228022.1 22802.21 22802.21 22802.21
# 3 3 3260741 Group4 0.0 0.00 0.00 0.00
# 4 4 3869420 Group1 1934710.0 967355.00 483677.50 483677.50
# 5 5 3950578 Group1 1975289.0 987644.50 493822.25 493822.25
# 6 6 2058883 Group2 617664.9 185299.47 185299.47 185299.47
它依赖于数据框中的Group
为factor
,并且threshhold
,below
和above
输入向量对应于级别Group
因子。为了使它更通用,我添加了一个below
向量,在你的情况下总是0?我对Group4
感到有些困惑,可能above
值应为1
?我会把详细信息留给你。