rstringsortingfor-loopif-statement

Extracting an outcome or string from a 'frtest' object (FRAIR package in R)


I'm trying to run a simulation experiment using simulated functional response data. My goal is to use frair_test from the FRAIR package to test for type-II versus type-III functional responses within one thousand simulations, and quantify the proportion of Type II vs. Type III outputs.

The problem is that I'm trying to use a for loop to implement this function and sort outputs, but I haven't been able to extract outputs such that I can use an if/then to summarise them.

The output is provided as an frtest object, and when called, looks something like this:

FUNCTIONAL RESPONSE TEST

Evidence for type-II response:  Yes
Evidence for type-III response: -

Type-II logistic regression output:
          Estimate Std. Error z value  Pr(>|z|)    
density -0.0216742  0.0014609 -14.836 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

I've tried converting this output to a string and searching for "Evidence for type-II response: Yes" within that string, but for some reason, when I convert to a string, the content changes.

Does anyone have any ideas Re: sorting these outputs as either Type II support or Type III support within a loop?

Here's a reproducible example:

library(frair); library(lamW)

RogersII <- function(N0, a, h, time){
  N0 - lamW::lambertW0(a * h * N0 * exp(-a * (time - h * N0)))/(a * h)
}

N0 <- c(4, 6, 10, 20, 60, 90, 120)

# Simulations
set.seed(123)
a.vec <- rlnorm(100, mean = log(1.704), sd = log(2)) 
h.vec <- rlnorm(100, mean = log(0.072), sd = log(2)) 
Ex1.TLow.II.Norm <- vector(mode = 'list', length = length(N0))
for (i in 1:length(N0)){
  for (j in 1:100){
    Ex1.TLow.II.Norm[[i]][j] <- RogersII(N0[i], a.vec[j], h.vec[j], 2)
  }
}

# Re-arranging data
N0 <- rep(c(4, 6, 10, 20, 60, 90, 120), times = 100)
Ne <- c()
for (i in 1:100){
  NeTemp <- c(Ex1.TLow.II.Norm[[1]][i], 
              Ex1.TLow.II.Norm[[2]][i], 
              Ex1.TLow.II.Norm[[3]][i], 
              Ex1.TLow.II.Norm[[4]][i], 
              Ex1.TLow.II.Norm[[5]][i], 
              Ex1.TLow.II.Norm[[6]][i], 
              Ex1.TLow.II.Norm[[7]][i])
  Ne <- c(Ne, NeTemp)
}; TLow.II.Norm <- data.frame(Ne, N0)

# frair_test
Out.List <-  vector(mode = 'list', length = length(100)); j <- 1; k <- 7
for (i in 1:100){
  SimDat <- TLow.II.Norm[j:k, ]
  Output <- frair_test(formula = Ne ~ N0, data = SimDat)
  Out.List[[i]] <- Output
  # Instead of store each output as a list item, I'd like to be able to store a simple and sortable version of the output, like "TypeII" or "TypeIII".
  j <- j + 7; k <- k + 7
}

Thank you in advance for any input!


Solution

  • That text is printed by the print.frtest method. It's a matter of running

    getAnywhere(print.frtest)
    

    and copy&paste the portion of code that does the printing.
    The function below is that code, edited to return a sub-string of what is printed.

    library(frair)
    
    getType <- function(x) {
      stopifnot(inherits(x, "frtest"))
      # this is pratically a copy&paste of a
      # part of getAnywhere(print.frtest)
      T2Coef <- coef(summary(x$modT2))
      T2CoefOut <- T2Coef[2, ] |> matrix(nrow = 1)
      #
      T3Coef <- coef(summary(x$modT3))
      T3CoefOut <- T3Coef[2:3, ]
      #
      Type <- if(T2CoefOut[1, 1] < 0 & T2CoefOut[1, 4] < 0.05) {
        "type-II response"
      } else if (T3CoefOut[1, 1] > 0 & 
                 T3CoefOut[1, 4] < 0.05 & 
                 T3CoefOut[2, 1] < 0 & 
                 T3CoefOut[2, 4] < 0.05) {
        "type-III response"
      }
      else {
        "No evidence for any response."
      }
      Type
    }
    
    lapply(Out.List[1:4], getType)
    #> [[1]]
    #> [1] "type-II response"
    #> 
    #> [[2]]
    #> [1] "type-II response"
    #> 
    #> [[3]]
    #> [1] "type-II response"
    #> 
    #> [[4]]
    #> [1] "type-II response"
    

    Created on 2025-03-20 with reprex v2.1.1