调用自定义apply.hourly函数时报错,逐行运行却正常的问题排查
xts自定义函数
apply.hourly的time<-方法报错问题解决 问题背景
自定义的apply.hourly函数用于调整xts时间序列的分辨率,此前运行正常,近日调用时出现如下错误:
unable to find an inherited method for function ‘time<-’ for signature ‘"x = xts"’
函数代码:
apply.hourly <- function(x, FUN, roundtime = "round", na.rm = TRUE){ if(!is.xts(x)){ stop("x must be an xts object") } if(!is.na(roundtime)){ if(roundtime == "round"){ time(x) <- round.POSIXt(terra::time(x), "hours") } else if(roundtime == "trunc"){ terra::time(x) <- terra::trunc.POSIXt(time(x), "hours") } else { stop("roundtime must be either round or trunc") } } ap <- endpoints(x,'hours') if(na.rm){ period.apply(x,ap,FUN, na.rm = TRUE) } else { period.apply(x,ap,FUN) } }
调用代码:
x <- xts(runif(6,1,100), order.by = as.POSIXct(c("2000-01-20 10:55","2000-01-20 10:59","2000-01-20 11:20","2000-01-20 12:35", "2000-01-20 12:45", "2000-01-20 13:45"))) apply.hourly(x, FUN = mean, roundtime = "round")
注:逐行执行函数内代码时无报错。
问题原因
- 命名空间冲突:函数中显式调用
terra::time(x)获取xts对象的时间,虽然terra::time()能读取xts的时间属性,但后续赋值时使用terra::time(x) <- ...会触发terra包的time<-方法,而该方法仅支持terra自身的SpatRaster/SpatVector对象,不兼容xts,因此报错。 - 逐行执行无错的原因:逐行执行时,R会优先调用xts包的
time()和time<-方法(因为当前对象是xts),而函数内强制指定terra::time,才引发了兼容性问题。
解决办法
修改函数,改用xts包原生的index()/index<-()接口处理时间索引,这是xts官方推荐的标准用法,避免和其他包的同名函数冲突:
apply.hourly <- function(x, FUN, roundtime = "round", na.rm = TRUE){ if(!is.xts(x)){ stop("x must be an xts object") } if(!is.na(roundtime)){ if(roundtime == "round"){ index(x) <- round.POSIXt(index(x), "hours") } else if(roundtime == "trunc"){ index(x) <- trunc.POSIXt(index(x), "hours") } else { stop("roundtime must be either round or trunc") } } ap <- endpoints(x,'hours') if(na.rm){ period.apply(x,ap,FUN, na.rm = TRUE) } else { period.apply(x,ap,FUN) } }
替代方案(不推荐)
如果坚持使用time()函数,需显式指定xts包的命名空间,避免调用terra的函数:
# 读取时间 xts::time(x) # 赋值时间 `time<-`(x, value = round.POSIXt(xts::time(x), "hours"))
但index()接口更直观且兼容性更好,优先推荐前者。
内容的提问来源于stack exchange,提问作者smoff
相关产品推荐
相关产品推荐

