负月作为两个日期之间的差异

Negative months as difference between two dates

我知道在 Whosebug 上有一些与此类似的帖子。但他们没有直接解决我的问题。这是我的问题:

我有一个名为 earliest_cr_line 的变量,其中包含日期为 Jan-01。这是一个字符串变量。我需要创建一个名为 "test" 的变量,它应该包含 earliest_cr_line 和 Dec-2007 之间的月差。为此,本人运行代码如下:

library(zoo)
loan_data$earliest_cr_line_date <- as.yearmon(loan_data$earliest_cr_line, "%b-%y")
ref_date <- as.yearmon("Dec-07", "%b-%y")
loan_data$test <- round((as.Date(ref_date) - 
as.Date(loan_data$earliest_cr_line_date))/(365.25/12))

但是,新创建的变量test也包含很多负数。我发现当将 earliest_cr_line 从字符串转换为 yearmon 时,R 误解了 1970 年之前的年份。例如,yearmon 将 Jan-60 转换为 2060 年 11 月而不是 1960 年 11 月。这就是导致负输出的原因。知道我应该如何解决这个问题吗?

谢谢。

Date的整数是一天,导致逐月判断不一致。 yearmon的整数是一年,这样一个月就变成了1/12,处理起来更简单一些。如果您从 zoo 的 yearmon 对象开始,那么我建议您坚持使用它,而不是尝试转换 to/from R 的 Date 对象。

处理错误的年份是一个恼人的 Y2K 问题......虽然下面的这个通常会起作用(假设你正在看的一切都是过去的),我敦促你从源头上解决这个问题。 (令我惊讶的是,某个地方仍然认为两位数的年份是可以接受的。*耸肩*)

vec <- c("Nov-60","Nov-70","Nov-71","Jan-01","Mar-05","Dec-07")
(out <- zoo::as.yearmon(vec, format="%b-%y"))
# [1] "Nov 2060" "Nov 1970" "Nov 1971" "Jan 2001" "Mar 2005" "Dec 2007"
(wrongcentury <- as.integer(gsub(".* ", "", out)) > as.integer(format(Sys.Date(), "%Y")))
# [1]  TRUE FALSE FALSE FALSE FALSE FALSE
vec[wrongcentury]
# [1] "Nov-60"
zoo::as.yearmon(gsub("-", "-19", vec[wrongcentury]), format = "%b-%Y")
# [1] "Nov 1960"
out[wrongcentury] <- zoo::as.yearmon(gsub("-", "-19", vec[wrongcentury]), format = "%b-%Y")
out
# [1] "Nov 1960" "Nov 1970" "Nov 1971" "Jan 2001" "Mar 2005" "Dec 2007"

编辑:来自 G. Grothendieck 的更简洁的推荐:

out <- zoo::as.yearmon(vec, format="%b-%y")
out - 100 * (out > zoo::as.yearmon(Sys.Date()))
# [1] "Nov 1960" "Nov 1970" "Nov 1971" "Jan 2001" "Mar 2005" "Dec 2007"

如果您的源数据接近 1920,则此推理解决方案将进一步失效。 (从源头上修复它的更多理由:-)