[英]Trying to apply a function rowwise to a dataframe to create a new column
I have a dataframe of services bookings. 我有一个服务预订的数据框。 Each booking has a contract start and end date. 每个预订都有合同开始和结束日期。 For a given reporting date, I want to determine if the contract is active and, if so, how much to bill based on the monthly billing rate. 对于给定的报告日期,我想确定合同是否有效,如果是,则根据月度结算率计算多少。 If the contract ends mid-month, I pro-rate the billing for the final month. 如果合同在月中结束,我会对最后一个月的结算进行评级。 Here's the dataframe: 这是数据帧:
> 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
I've written a function using lubridate to calculate the monthly billing. 我已经使用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
}
I then set a billing date and apply the function rowwise to the data frame: 然后我设置开票日期并将函数rowwise应用于数据框:
billing_date <- as.Date("2019-03-29")
revenue_for_month <-bookings %>%
rowwise() %>%
mutate(Revenue = monthly_revenue(billing_date, MonthlyRate, ContractStart, ContractEnd))
Which results in the following error: 这导致以下错误:
Error in mutate_impl(.data, dots) :
Evaluation error: non-numeric argument to binary operator.
I can't tell if the problem is with my function or how I'm iterating. 我不知道问题是我的功能还是我的迭代。 Any help would be sincerely appreciated. 任何帮助将是真诚的感谢。
[follow-up based on comments received] I am using the following library calls: [根据收到的评论进行跟进]我正在使用以下库调用:
library(tidyverse)
library(lubridate)
And here is the dput output for my dataframe: 这是我的数据帧的输出输出:
> 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"))
I've changed your function up quite a bit, because I ran into numerous issues. 我已经改变了你的功能,因为我遇到了很多问题。 Now it works for me: 现在它对我有用:
monthly_revenue <- function(reporting_date, monthly_rate, start, end) {
contract_int <- interval(start, end) # Contract interval
EoM_int <- interval(start, ceiling_date(as_date(end),unit="month")-1)
reporting_date <- as_datetime(reporting_date)
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% EoM_int) {
val <- day(end) / day(ceiling_date(as_date(end),unit="month")-1) # prorate monthly charges
} else { # Not within contract
val <- 0 # zero revenue
}
return(val * monthly_rate)
}
Your dplyr
code is correct and runs fine. 你的dplyr
代码是正确的,运行正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.