负数为两个日期之间的差额

问题描述 投票:1回答:1

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

我有一个名为earlyest_cr_line的变量,其中包含日期为Jan-01。这是一个字符串变量。我需要创建一个名为“ test”的变量,其中应包含earlyest_cr_line和2007年12月之间的月份差异。为此,我运行了以下代码:

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))

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

谢谢。

r zoo as.date
1个回答
2
投票

Date的整数是一天,因此每天的确定不一致。 yearmon的整数是一年,因此使1/12的月份就更简单了。如果您从zoo的yearmon对象开始,那么我建议您坚持使用它,而不要尝试与R的Date对象进行转换。

处理错误的年份是一个令人烦恼的Y2K问题...尽管下面的方法通常可以解决(假设您正在查看的所有内容都是过去的),但我恳请您从根本上解决此问题。 (令我惊讶的是,某些地方仍然认为2位数的年份是可以接受的。*耸肩*)]

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"

Edit:来自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,那么这种推论性解决方案将进一步失效。 (更多原因需要从源头修复它:-)

© www.soinside.com 2019 - 2024. All rights reserved.