You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用自定义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")

注:逐行执行函数内代码时无报错。

问题原因

  1. 命名空间冲突:函数中显式调用terra::time(x)获取xts对象的时间,虽然terra::time()能读取xts的时间属性,但后续赋值时使用terra::time(x) <- ...会触发terra包的time<-方法,而该方法仅支持terra自身的SpatRaster/SpatVector对象,不兼容xts,因此报错。
  2. 逐行执行无错的原因:逐行执行时,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 03:07:36