我有以下创建函数用于我的工作目的:
monthsCounter <- function(date1, date2) {
if (date2 < date1) {
warning("Can't calculate result if second date is older than first date")
} else {
date1_Y <- as.numeric(format(date1, '%Y'))
date2_Y <- as.numeric(format(date2, '%Y'))
date1_M <- as.numeric(format(date1, '%m'))
date2_M <- as.numeric(format(date2, '%m'))
if (date2_Y == date1_Y) {
date2_M - date1_M
} else if (date2_M < date1_M) {
max(0, date2_Y - date1_Y - 1)*12 + 12 - date1_M + date2_M
} else {
max(0, date2_Y - date1_Y)*12 + date2_M - date1_M
}
}
}
在一个坚果中,无论月份日期如何,它都会在两个日期之间计算几个月。
当我在我的数据框中mapply
时:
allData$monthsSinceIssue <- mapply(monthsCounter, allData$start_month, allData$Date)
计算需要很长时间。
问题:您对如何优化我的功能以使其计算更快有任何建议吗?
更新:基于@Sotos和@MrGumble的建议我最终得到了这个功能:
monthsCounter <- function(date1, date2) {
date1_Y <- as.numeric(format(date1, '%Y'))
date2_Y <- as.numeric(format(date2, '%Y'))
date1_M <- as.numeric(format(date1, '%m'))
date2_M <- as.numeric(format(date2, '%m'))
ifelse(date2 < date1, NA,
ifelse(date2_Y == date1_Y, date2_M - date1_M,
ifelse(date2_M < date1_M, max(0, date2_Y - date1_Y - 1)*12 + 12 - date1_M + date2_M, max(0, date2_Y - date1_Y)*12 + date2_M - date1_M)))
}
UPDATE2:我偶然发现了@MrGumble可能指向的问题。 date2 - date1 > 1
时的情况。
因此不得不更新功能:
monthsCounter <- function(date1, date2) {
date1_Y <- as.numeric(format(date1, '%Y'))
date2_Y <- as.numeric(format(date2, '%Y'))
date1_M <- as.numeric(format(date1, '%m'))
date2_M <- as.numeric(format(date2, '%m'))
ifelse(date2 < date1, NA,
ifelse(date2_Y == date1_Y, date2_M - date1_M,
ifelse(date2_M < date1_M, pmax(0, date2_Y - date1_Y - 1)*12 + 12 - date1_M + date2_M, pmax(0, date2_Y - date1_Y)*12 + date2_M - date1_M)))
}
基本上将max
更改为pmax
。
答案 0 :(得分:1)
R固有地适用于矢量。您的函数可以轻松地接受两列作为参数:
allData$monthsSinceIssue <- monthsCounter(allData$start_month, allData$Date)
虽然您必须将max
更改为pmax
。也可以像Sotos建议的那样(更新到ifelse
功能)。
最后,我建议你返回NA
而不是警告。