如何计算Growstart与Growend间的月份数(起始月>结束月场景)
计算跨年度生长季的月份差
我们需要计算growstart(生长季起始月)与growend(生长季结束月)之间的月份数,但当起始月大于结束月(如12月到次年4月)时,直接转换为日期计算会得到负数结果。以下是相关数据集及尝试过的代码:
数据集
structure(list(gid = c(100468L, 100468L, 100468L, 100468L, 100468L, 104078L, 104078L, 104078L, 104078L, 104078L, 104078L, 115615L, 115615L, 115615L, 115615L, 115615L, 115615L), country = c("Namibia", "Namibia", "Namibia", "Namibia", "Namibia", "Namibia", "Namibia", "Namibia", "Namibia", "Namibia", "Namibia", "Congo, Democratic Republic of (Zaire)", "Congo, Democratic Republic of (Zaire)", "Congo, Democratic Republic of (Zaire)", "Congo, Democratic Republic of (Zaire)", "Congo, Democratic Republic of (Zaire)", "Congo, Democratic Republic of (Zaire)"), xcoord = c("13.75", "13.75", "13.75", "13.75", "13.75", "18.75", "18.75", "18.75", "18.75", "18.75", "18.75", "27.25", "27.25", "27.25", "27.25", "27.25", "27.25"), ycoord = c("-20.25", "-20.25", "-20.25", "-20.25", "-20.25", "-17.75", "-17.75", "-17.75", "-17.75", "-17.75", "-17.75", "-9.75", "-9.75", "-9.75", "-9.75", "-9.75", "-9.75"), km2 = c("3282.64642089", "3282.64642089", "3282.64642089", "3282.64642089", "3282.64642089", "3233.1051487", "3233.1051487", "3233.1051487", "3233.1051487", "3233.1051487", "3233.1051487", "3122.97751422", "3122.97751422", "3122.97751422", "3122.97751422", "3122.97751422", "3122.97751422" ), maincrop = c(52L, 52L, 52L, 52L, 52L, 37L, 37L, 37L, 37L, 37L, 37L, 37L, 37L, 37L, 37L, 37L, 37L), crop = c("Others annual", "Others annual", "Others annual", "Others annual", "Others annual", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava", "Cassava" ), growstart = c(12L, 12L, 12L, 12L, 12L, 9L, 9L, 9L, 9L, 9L, 9L, 5L, 5L, 5L, 5L, 5L, 5L), growend = c(4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 12L, 12L, 12L, 12L, 12L, 12L), Time = structure(c(4352, 4383, 4717, 4414, 4442, 9862, 10135, 10166, 10196, 9893, 9921, 13057, 13088, 13118, 12904, 12935, 12965), class = "Date"), harvestYear = c(1982L, 1982L, 1983L, 1982L, 1982L, 1997L, 1998L, 1998L, 1998L, 1997L, 1997L, 2005L, 2005L, 2005L, 2005L, 2005L, 2005L)), row.names = c(1L, 2L, 3L, 4L, 5L, 40000L, 40001L, 40002L, 40003L, 40004L, 40005L, 200000L, 200001L, 200002L, 200003L, 200004L, 200005L), class = "data.frame")
尝试过的代码
vhi.crop.gs$Datestart<-gsub(" ","",paste(vhi.crop.gs$harvestYear,"-",vhi.crop.gs$growstart,"-","01")) vhi.crop.gs$Datestart<-as.Date(vhi.crop.gs$Datestart,format="%Y-%m-%d") vhi.crop.gs$Dateend<-gsub(" ","",paste(vhi.crop.gs$harvestYear,"-",vhi.crop.gs$growend,"-","01")) vhi.crop.gs$Dateend<-as.Date(vhi.crop.gs$Dateend,format="%Y-%m-%d") vhi.crop.gs %>% group_by(gid, country, xcoord, ycoord, crop, maincrop, harvestYear) %>% mutate(Months_difference = (interval(ymd(Datestart), ymd(Dateend))) %/% months(1))
解决方案
方法一:直接通过月份数值计算
无需转换为日期,直接根据月份大小判断是否跨年度,计算月份差:
library(dplyr) vhi.crop.gs <- vhi.crop.gs %>% mutate( Months_difference = ifelse(growstart > growend, (12 - growstart) + growend, growend - growstart) )
方法二:修正日期年份后计算
如果需要保留日期格式用于后续操作,可根据生长季是否跨年度调整日期的年份:
library(lubridate) library(dplyr) vhi.crop.gs <- vhi.crop.gs %>% mutate( # 跨年度时,起始年份为收获年份减1,否则为收获年份 Datestart = ymd(paste(ifelse(growstart > growend, harvestYear - 1, harvestYear), growstart, "01", sep = "-")), # 跨年度时,结束年份为收获年份,否则为收获年份 Dateend = ymd(paste(ifelse(growstart > growend, harvestYear, harvestYear), growend, "01", sep = "-")), Months_difference = interval(Datestart, Dateend) %/% months(1) )
两种方法都能解决跨年度生长季月份差为负的问题:方法一简洁高效,适合仅需月份差的场景;方法二保留了正确的日期序列,适合需要后续日期处理的场景。
内容的提问来源于stack exchange,提问作者Shunrei
相关产品推荐
相关产品推荐

