rfunctionenvironment-variables

Using functions from other packages with .Call and undefined objects


As an example from the TTR package, the function runMin() is returned as:

function (x, n = 10, cumulative = FALSE) 
{
    x <- try.xts(x, error = as.matrix)
    if (n < 1 || n > NROW(x)) 
        stop(sprintf("n = %d is outside valid range: [1, %d]", 
            n, NROW(x)))
    if (NCOL(x) > 1) {
        stop("ncol(x) > 1. runMin only supports univariate 'x'")
    }
    if (cumulative) {
        NAs <- sum(is.na(x))
        if (NAs > 0) {
            if (any(is.na(x[-(1:NAs)]))) 
                stop("Series contains non-leading NAs")
            if (NAs + n > NROW(x)) 
                stop("not enough non-NA values")
        }
        beg <- 1 + NAs
        result <- double(NROW(x))
        result[beg:NROW(x)] <- cummin(x[beg:NROW(x)])
        is.na(result) <- seq_len(n - 1 + NAs)
    }
    else {
        result <- .Call(C_runmin, x, n)
    }
    reclass(result, x)
}
<bytecode: 0x0000027e2e75cb70>
<environment: namespace:TTR>

try.xts and reclass are from the package xts, so I load that first (library(xts)) and everything seems to work except "C_runmin" is not found:

library(xts)
RunMin<-function (x, n = 10, cumulative = FALSE) 
{
  x <- try.xts(x, error = as.matrix)
  if (n < 1 || n > NROW(x)) 
    stop(sprintf("n = %d is outside valid range: [1, %d]", 
                 n, NROW(x)))
  if (NCOL(x) > 1) {
    stop("ncol(x) > 1. runMin only supports univariate 'x'")
  }
  if (cumulative) {
    NAs <- sum(is.na(x))
    if (NAs > 0) {
      if (any(is.na(x[-(1:NAs)]))) 
        stop("Series contains non-leading NAs")
      if (NAs + n > NROW(x)) 
        stop("not enough non-NA values")
    }
    beg <- 1 + NAs
    result <- double(NROW(x))
    result[beg:NROW(x)] <- cummin(x[beg:NROW(x)])
    is.na(result) <- seq_len(n - 1 + NAs)
  }
  else {
    result <- .Call(C_runmin, x, n)
  }
  reclass(result, x)
}


> RunMin(x=rnorm(10,1,1),5)
Error in RunMin(x = rnorm(10, 1, 1), 5) : object 'C_runmin' not found

Even though the original runs fine:

> TTR::runMin(x=rnorm(10,1,1),5)
 [1]         NA         NA         NA         NA 0.06589477 0.06589477 0.21588468 0.21588468 0.21588468 0.21588468

Is this an environment issue? Where can I find where 'C_runmin' is defined? Any help is appreciated.


Solution

  • RunMin<- function (x, n = 10, cumulative = FALSE) 
    {
      
      x <- xts::try.xts(x, error = as.matrix)
      if (n < 1 || n > NROW(x)) 
        stop(sprintf("n = %d is outside valid range: [1, %d]", 
                     n, NROW(x)))
      if (NCOL(x) > 1) {
        stop("ncol(x) > 1. runMin only supports univariate 'x'")
      }
      if (cumulative) {
        NAs <- sum(is.na(x))
        if (NAs > 0) {
          if (any(is.na(x[-(1:NAs)]))) 
            stop("Series contains non-leading NAs")
          if (NAs + n > NROW(x)) 
            stop("not enough non-NA values")
        }
        beg <- 1 + NAs
        result <- double(NROW(x))
        result[beg:NROW(x)] <- cummin(x[beg:NROW(x)])
        is.na(result) <- seq_len(n - 1 + NAs)
      }
      else {
        result <- .Call(TTR:::C_runmin, x, n)
      }
      xts::reclass(result, x)
      return(result)
    }
    
    set.seed(42)
    x <- rnorm(10, 1, 1)
    
    (TTR_res <- TTR::runMin(x, 5))
    #>  [1]        NA        NA        NA        NA 0.4353018 0.4353018 0.8938755
    #>  [8] 0.8938755 0.8938755 0.8938755
    
    UDF_res <- RunMin(x, 5)
    
    XTS_res <- .Call(xts:::C_roll_min, x, 5)
    
    CRM_res <- .Call(TTR:::C_runmin, x, 5)
    
    all(sapply(list(UDF_res, XTS_res, CRM_res), FUN = identical, TTR_res))
    #> [1] TRUE
    
    UDF_res
    #>  [1]        NA        NA        NA        NA 0.4353018 0.4353018 0.8938755
    #>  [8] 0.8938755 0.8938755 0.8938755
    

    Created on 2025-02-28 with reprex v2.1.1