我有一个服务预订数据框。每个预订都有合同开始和结束日期。对于给定的报告日期,我想确定合同是否有效,如果有效,根据每月计费率计费多少。如果合同在月中结束,我会按比例计算最后一个月的账单。这是数据框:
> bookings
Account Service MonthlyRate ContractStart ContractEnd
1 A W 50 2018-01-01 2018-12-31
2 A X 75 2018-03-15 2019-03-14
3 B W 60 2018-02-28 2018-09-30
4 B X 90 2018-05-12 2019-08-11
5 B Y 45 2018-02-28 2018-09-30
6 C Y 50 2018-07-31 2019-04-30
7 D W 65 2019-01-01 2019-03-31
8 D Y 50 2018-09-01 2019-05-31
9 D Z 110 2018-08-22 2019-12-31
10 E Z 100 2018-10-01 2019-09-30
我编写了一个使用 lubridate 计算每月账单的函数。
monthly_revenue <- function(reporting_date, monthly_rate, start, end) {
contract_int <- interval(start, end) # Contract interval
# Calculate interval ending the last day of the month of contract end
end_of_month <- end
day(end_of_month) <- days_in_month(end)
end_of_month_int <- interval(start, end_of_month)
# Check if reporting date is within contract interval
if(reporting_date %within% contract_int) {
val <- 1 # bill for entire month
# If not within interval, check if contract is in its last month
} else if (reporting_date %within% end_of_month_int) {
val <- day(end) / days_in_month(end) # prorate monthly charges
} else { # Not within contract
val <- 0 # zero revenue
}
val * monthly_rate
}
然后我设置一个计费日期并将函数逐行应用于数据框:
billing_date <- as.Date("2019-03-29")
revenue_for_month <-bookings %>%
rowwise() %>%
mutate(Revenue = monthly_revenue(billing_date, MonthlyRate, ContractStart, ContractEnd))
这会导致以下错误:
Error in mutate_impl(.data, dots) :
Evaluation error: non-numeric argument to binary operator.
我不知道问题出在我的函数上还是我的迭代方式上。任何帮助将不胜感激。
[根据收到的评论跟进] 我正在使用以下库调用:
library(tidyverse)
library(lubridate)
这是我的数据框的 dput 输出:
> dput(bookings)
structure(list(Account = c("A", "A", "B", "B", "B", "C", "D",
"D", "D", "E"), Type = c("W", "X", "W", "X", "Y", "Y", "W", "Y",
"Z", "Z"), MonthlyRate = c(50L, 75L, 60L, 90L, 45L, 50L, 65L,
50L, 110L, 100L), ContractStart = structure(c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_), class = "Date"), ContractEnd = structure(c(NA_real_,
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_, NA_real_), class = "Date")), .Names = c("Account",
"Type", "MonthlyRate", "ContractStart", "ContractEnd"), row.names = c(NA,
-10L), spec = structure(list(cols = structure(list(Account = structure(list(), class = c("collector_character",
"collector")), Type = structure(list(), class = c("collector_character",
"collector")), MonthlyRate = structure(list(), class = c("collector_integer",
"collector")), ContractStart = structure(list(), class = c("collector_character",
"collector")), ContractEnd = structure(list(), class = c("collector_character",
"collector"))), .Names = c("Account", "Type", "MonthlyRate",
"ContractStart", "ContractEnd")), default = structure(list(), class = c("collector_guess",
"collector"))), .Names = c("cols", "default"), class = "col_spec"), class = c("tbl_df",
"tbl", "data.frame"))