Dylan_Gomes
Dylan_Gomes

Reputation: 2280

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.

Upvotes: 1

Views: 62

Answers (1)

M--
M--

Reputation: 29153

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

Upvotes: 1

Related Questions