Running ‘allExamples.R’ [0s/1s]
  Running ‘rfPermute_supported.R’ [0s/1s]
  Running ‘stdUsage.R’ [8s/13s]
  Running ‘testBinaryClass.R’ [3s/4s]
  Running ‘testCaret.R’ [13s/21s]
  Running ‘testMultiClass.cpp.R’ [4s/6s]
  Running ‘test_Xtestmerger.R’ [2s/3s]
Running the tests in ‘tests/stdUsage.R’ failed.
Complete output:
  > if(!interactive()) Sys.setenv(RGL_USE_NULL=TRUE) #disable RGL for headless machines
  > library(forestFloor)
  > library(randomForest)
  randomForest 4.6-14
  Type rfNews() to see new features/changes/bug fixes.
  > #simulate data
  > obs=2000
  > vars = 6 
  > 
  > X = data.frame(replicate(vars,rnorm(obs)))
  > Xtest = data.frame(replicate(vars,rnorm(obs)*3))
  > Y = with(X, X1^2 + sin(X2*pi) + 2 * X3 * X4 + .5 * rnorm(obs))
  > 
  > 
  > #grow a forest, remeber to include inbag
  > rf41=randomForest(X,Y,keep.inbag = TRUE,sampsize=499,ntree=100,importance = F)
  > #compute feature contributions
  > out = tryCatch({ff41 = forestFloor(rf41,X,bootstrapFC = TRUE,impType=1)},warning = function(w) w)
  > if(out$message != "found nothing of importance, revert to fallback") stop("wrong warning")
  > 
  > #if(colnames(ff41$importance) != "%IncMSE") stop("wrong imp")
  > ff41 = forestFloor(rf41,X,bootstrapFC = TRUE,impType=2)
  > if(colnames(ff41$importance) != "IncNodePurity") stop("wrong imp")
  > ff41 = forestFloor(rf41,X,bootstrapFC = TRUE,impType=NULL)
  > if(colnames(ff41$importance) != "IncNodePurity") stop("wrong imp")
  > 
  > #grow a forest, remeber to include inbag
  > rf42=randomForest(X,Y,keep.inbag = TRUE,sampsize=499,ntree=100,importance = T)
  > #compute feature contributions
  > ff42 = forestFloor(rf42,X,bootstrapFC = TRUE,impType=1)
  > if(colnames(ff42$importance) != "%IncMSE") stop("wrong imp")
  > ff42 = forestFloor(rf42,X,bootstrapFC = TRUE,impType=2)
  > if(colnames(ff42$importance) != "IncNodePurity") stop("wrong imp")
  > ff42 = forestFloor(rf42,X,bootstrapFC = TRUE,impType=NULL)
  > if(colnames(ff42$importance) != "%IncMSE") stop("wrong imp")
  > 
  > 
  > 
  > 
  > #test accuracy of feature contributions
  > #y_hat_OOB = row sum FC + Y_grandMean
  > FC.residuals = rf42$predicted - apply(ff42$FCmatrix[ff42$isTrain,],1,sum) - mean(Y)
  > if(max(abs(FC.residuals))>1E-12) stop(
  +   paste0("When testing if:  y_hat_OOB = row sum FCmatrix + Y_grandMean
  +   one/some FCs error exceed allowed 1e-12, found.error=",max(abs(FC.residuals)))
  + )
  > 
  > #test same results are reached with Xtest
  > ff43 = forestFloor(rf42,X,Xtest,bootstrapFC = TRUE)
  > if(max(abs(ff43$FCmatrix[ff43$isTrain,]-ff42$FCmatrix)) > 1E-12) stop(
  +   "forestFloor with/without Xtest gives different feature contributions"
  + )
  > 
  > 
  > #print forestFloor
  > print(ff42) 
  this is a forestFloor_regression object 
  
        this object can be plotted in 2D with plot(x), see help(plot.forestFloor) 
  
        this object can be plotted in 3D with show3d(x), see help(show3d) 
  
        
  
        x contains following internal elements: 
    FCmatrix X Y imp_ind importance isTrain> 
  > #plot partial functions of most important variables first
  > plot(ff42,orderByImportance=TRUE) 
  [1] "compute goodness-of-fit with leave-one-out k-nearest neighbor(guassian weighting), kknn package"
  > plot(ff43,orderByImportance=TRUE)
  [1] "compute goodness-of-fit with leave-one-out k-nearest neighbor(guassian weighting), kknn package"
  > 
  > #Non interacting functions are well displayed, whereas X3 and X4 are not
  > #by applying different colourgradient, interactions reveal themself 
  > #also a k-nearest neighbor fit is applied to evaluate goodness of fit
  > Col=fcol(ff43,3,orderByImportance=FALSE)
  > plot(ff43,col=Col,plot_GOF=TRUE,speed=T) 
  [1] "compute goodness-of-fit with leave-one-out k-nearest neighbor(guassian weighting), kknn package"
  > 
  > 
  > ##make test set grey tone to show if point of test is extrapolated
  > Col=fcol(ff43,3,orderByImportance=FALSE,plotTest="andTrain",alpha=.2)
  > Col[ff43$isTrain] = "#000000FF"
  > plot(ff43,col=Col,speed=T,plotTest="andTrain",plot_GOF=F) 
  > 
  > 
  > #if ever needed, k-nearest neighbor parameters for goodness-of-fit can be access through convolute_ff
  > #a new fit will be calculated and added to forstFloor object as ff42$FCfit
  > ff43 = convolute_ff(ff43,userArgs.kknn=alist(kernel="epanechnikov",kmax=5))
  > plot(ff43,col=Col,plot_GOF=TRUE)
  > 
  > #in 3D the interaction between X3 and X reveals itself completely
  > show3d(ff43,3:4,col=Col,plot.rgl=list(size=5),orderByImportance=FALSE)
  > Col=fcol(ff43,1:2,orderByImportance=FALSE)
  > show3d(ff43,1:2,col=Col,plot.rgl=list(size=5),orderByImportance=FALSE)
  > 
  > 
  > Col=fcol(ff43,1:2,plotTest="andTrain",orderByImportance=FALSE)
  > show3d(ff43,1:2,col=Col,plot.rgl=list(size=5),orderByImportance=FALSE)
  > 
  > 
  > 
  > #although no interaction, a joined additive effect of X1 and X2
  > #colour by FC-component FC1 and FC2 summed
  > Col = fcol(ff43,1:2,orderByImportance=FALSE,X.m=FALSE,RGB=TRUE,plotTest = "a")
   ----------- FAILURE REPORT -------------- 
   --- failure: the condition has length > 1 ---
   --- srcref --- 
  : 
   --- package (from environment) --- 
  forestFloor
   --- call from context --- 
  fcol(ff43, 1:2, orderByImportance = FALSE, X.m = FALSE, RGB = TRUE, 
      plotTest = "a")
   --- call from argument --- 
  if (!class(colM) %in% c("data.frame", "matrix")) {
      tryCatch({
          colM = matrix(colM, ncol = 1)
      }, error = function(e) stop(paste("input ff was neither data.frame or matrix and \ncould not be coerced to matrix:", 
          e$message)))
  }
   --- R stacktrace ---
  where 1: fcol(ff43, 1:2, orderByImportance = FALSE, X.m = FALSE, RGB = TRUE, 
      plotTest = "a")
  
   --- value of length: 2 type: logical ---
  [1] FALSE  TRUE
   --- function from context --- 
  function (ff, cols = NULL, orderByImportance = NULL, plotTest = NULL, 
      X.matrix = TRUE, hue = NULL, saturation = NULL, brightness = NULL, 
      hue.range = NULL, sat.range = NULL, bri.range = NULL, alpha = NULL, 
      RGB = NULL, byResiduals = FALSE, max.df = 3, imp.weight = NULL, 
      imp.exp = 1, outlier.lim = 3, RGB.exp = NULL) 
  {
      if (!X.matrix) 
          if (class(ff) == "forestFloor_multiClass") 
              stop("cannot colour by feature contributions for object of class\n         'forestFloor_multiClass'. Set X.matrix=TRUE")
      ib <- function(x, low, high) (x - low) * (high - x) > 0
      span <- function(x, mid, width) if (min(x) != max(x)) {
          ((x - min(x))/(max(x) - min(x)) - 0.5) * width + mid
      }
      else {
          x[] = mid
      }
      auto.range = function(level, low = 0, high = 1) abs(min(level - 
          low, high - level)) * 2
      contain = function(x, low = 0, high = 1) {
          x[x > high] = high
          x[x < low] = low
          x
      }
      if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
          plotThese = checkPlotTest(plotTest, ff$isTrain)
          if (!(all(plotThese))) {
              if (class(ff) == "forestFloor_multiClass") {
                  ff$FCarray = ff$FCarray[plotThese, , ]
              }
              else {
                  if (class(ff) == "forestFloor_regression") {
                    ff$FCmatrix = ff$FCmatrix[plotThese, ]
                  }
              }
              ff$Y = ff$Y[plotThese]
              ff$X = ff$X[plotThese, ]
          }
      }
      if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
          if (byResiduals) {
              if (is.null(ff$FCfit)) {
                  print("no $FCfit found, computing tempoary LOO-kNN-gaussion fit to main affect")
                  print("use ff = convolute_ff(ff) to compute a fixed fit")
                  ff = convolute_ff(ff)
              }
              colM = ff$FCmatrix - ff$FCfit
          }
          else {
              if (X.matrix) 
                  colM = ff$X
              else colM = ff$FCmatrix
          }
          if (is.null(imp.weight)) 
              imp.weight = TRUE
          if (is.null(orderByImportance)) 
              orderByImportance = TRUE
      }
      else {
          colM = ff
          if (is.null(imp.weight)) 
              imp.weight = FALSE
          if (is.null(orderByImportance)) 
              orderByImportance = FALSE
      }
      if (orderByImportance) 
          if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
              colM = colM[, ff$imp_ind]
          }
          else {
              warning("orderByImportance=TRUE takes no effect for non 'forestFloor'-class. As if set to NULL or FALSE...")
          }
      if (!class(colM) %in% c("data.frame", "matrix")) {
          tryCatch({
              colM = matrix(colM, ncol = 1)
          }, error = function(e) stop(paste("input ff was neither data.frame or matrix and \ncould not be coerced to matrix:", 
              e$message)))
      }
      colM = data.frame(colM)
      if (is.null(cols)) 
          cols = 1:dim(colM)[2]
      if (length(cols) < 1 || !is.numeric(cols) || any(!cols %in% 
          1:dim(colM)[2])) {
          stop("no cols selected or is not integer/numeric or wrong coloumns")
      }
      sel.colM = data.frame(colM[, cols])
      sel.cols = 1:length(cols)
      if (is.null(RGB)) 
          if (length(cols) == 1) 
              RGB = TRUE
          else RGB = FALSE
      if (!RGB) {
          if (is.null(saturation)) 
              saturation = 0.85
          if (is.null(brightness)) 
              brightness = 0.75
          if (is.null(hue)) 
              hue = 0.25
      }
      else {
          if (is.null(saturation)) 
              saturation = 1
          if (is.null(brightness)) 
              brightness = 0.75
          if (is.null(hue)) 
              hue = 0.66
          if (is.null(RGB.exp)) 
              RGB.exp = 1.2
          if (is.null(hue.range)) 
              hue.range = 2
      }
      as.numeric.factor <- function(x, rearrange = TRUE) {
          if (is.numeric(x)) 
              return(x)
          if (rearrange) 
              x = match(x, levels(droplevels(x)))
          else x = match(x, levels(x))
          return(x)
      }
      for (i in 1:dim(sel.colM)[2]) {
          if (is.factor(sel.colM[, i])) {
              this.fac = as.numeric.factor(sel.colM[, i])
              sel.colM[, i] = this.fac
          }
          if (is.character(sel.colM[, i])) 
              sel.colM[, i] = as.numeric(sel.colM[, i])
      }
      sel.colM = box.outliers(sel.colM, limit = outlier.lim)
      if (imp.weight && length(cols) > 1) {
          if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
              sel.imp = ff$importance[cols]
              non.negative.imp = sel.imp + min(sel.imp)
              sumnorm.imp = non.negative.imp/sum(non.negative.imp)
              exp.imp = sumnorm.imp^imp.exp
              impM = t(replicate(dim(colM)[1], exp.imp))
              sel.colM = sel.colM * impM
              sel.colM = sel.colM/max(sel.colM)
          }
          else {
              warning("importance weighting only possible for class 'forestFloor'")
          }
      }
      if (any(!c(class(hue), class(saturation), class(brightness)) %in% 
          c("numeric", "integer"))) {
          stop("hue, saturation and brightness must be of class numeric or integer")
      }
      hue = hue - floor(hue)
      saturation = max(min(saturation, 1), 0)
      brightness = max(min(brightness, 1), 0)
      if (RGB == TRUE) {
          if (is.null(bri.range)) 
              bri.range = 0.05
          if (is.null(alpha)) 
              alpha = 0.7
          len.colM = box.outliers(sel.colM, limit = Inf)
          if (dim(len.colM)[2] == 1) 
              nX = as.numeric(len.colM[, 1])
          else nX = as.numeric(apply(len.colM, 1, mean))
          hsvcol = t(sapply(nX, function(x) rgb2hsv(x^RGB.exp, 
              1 - x^RGB.exp - (1 - x)^RGB.exp, (1 - x)^RGB.exp)))
          hue.vec = hsvcol[, 1] * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - floor(hue.vec[hue.vec > 
              1])
          hsvcol[, 1] = hue.vec
          sat.range = auto.range(saturation)
          hsvcol[, 2] = span(hsvcol[, 2], saturation, sat.range)
          hsvcol[, 2] = contain(hsvcol[, 2])
          bri.range = auto.range(brightness)
          hsvcol[, 3] = span(hsvcol[, 3], brightness, bri.range)
          hsvcol[, 3] = contain(hsvcol[, 3])
          colours = apply(hsvcol, 1, function(x) hsv(x[1], x[2], 
              x[3], alpha = alpha))
          return(colours)
      }
      col.df = length(cols)
      if (!max.df %in% c(1, 2, 3)) 
          stop("fcol input 'max.df' must be set to either 1, 2 or 3")
      if (col.df > max.df) {
          len.colM = box.outliers(prcomp(sel.colM)$x[, 1:max.df], 
              limit = Inf)
          col.df = max.df
      }
      else {
          len.colM = box.outliers(sel.colM, limit = Inf)
      }
      if (is.null(hue.range)) {
          if (col.df == 1) 
              hue.range = 0.85
          if (col.df == 2) 
              hue.range = 1
          if (col.df == 3) 
              hue.range = 1
      }
      if (is.null(sat.range)) {
          if (col.df == 1) 
              sat.range = "not used"
          if (col.df == 2) 
              sat.range = auto.range(saturation)
          if (col.df == 3) 
              sat.range = auto.range(saturation)
      }
      if (is.null(bri.range)) {
          if (col.df == 1) 
              bri.range = "not used"
          if (col.df == 2) 
              bri.range = "not used"
          if (col.df == 3) 
              bri.range = auto.range(brightness)
      }
      if (is.null(alpha)) 
          alpha = min(1, 400/dim(len.colM)[1])
      if (col.df == 1) {
          hue.vec = as.numeric(len.colM[, 1]) * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - floor(hue.vec[hue.vec > 
              1])
          colours = hsv(h = hue.vec, s = saturation, v = brightness, 
              alpha = alpha)
      }
      if (col.df == 2) {
          hsvcol = t(rgb2hsv(len.colM[, 1], len.colM[, 2], 1 - 
              apply(len.colM, 1, mean)))
          hue.vec = hsvcol[, 1] * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - 1
          hsvcol[, 1] = hue.vec
          hsvcol[, 2] = ((len.colM[, 1] - mean(len.colM[, 1]))^2 + 
              (len.colM[, 2] - mean(len.colM[, 2]))^2)^sat.range * 
              saturation
          hsvcol[, 2] = hsvcol[, 2]/max(hsvcol[, 2])
          hsvcol[, 3] = brightness
          colours = hsv(hsvcol[, 1], hsvcol[, 2], hsvcol[, 3], 
              alpha = alpha)
      }
      if (col.df == 3) {
          hsvcol = t(rgb2hsv(len.colM[, 1], len.colM[, 2], len.colM[, 
              3]))
          hue.vec = hsvcol[, 1] * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - 1
          hsvcol[, 1] = hue.vec
          span.sat = span(hsvcol[, 2], saturation, sat.range)
          hsvcol[, 2] = contain(span.sat)
          mean.bri = apply(len.colM, 1, mean)
          span.bri = span(mean.bri, brightness, bri.range)
          hsvcol[, 3] = contain(span.bri)
          colours = hsv(hsvcol[, 1], hsvcol[, 2], hsvcol[, 3], 
              alpha = alpha)
      }
      return(colours)
  }
  <bytecode: 0x559e31578f30>
  <environment: namespace:forestFloor>
   --- function search by body ---
  Function fcol in namespace forestFloor has this body.
   ----------- END OF FAILURE REPORT -------------- 
  Fatal error: the condition has length > 1
Running the tests in ‘tests/testMultiClass.cpp.R’ failed.
Complete output:
  > if(!interactive()) Sys.setenv(RGL_USE_NULL=TRUE) #disable RGL for headless machines
  > library(randomForest)
  randomForest 4.6-14
  Type rfNews() to see new features/changes/bug fixes.
  > library(forestFloor)
  > require(utils)
  > 
  > data(iris)
  > iris
      Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
  1            5.1         3.5          1.4         0.2     setosa
  2            4.9         3.0          1.4         0.2     setosa
  3            4.7         3.2          1.3         0.2     setosa
  4            4.6         3.1          1.5         0.2     setosa
  5            5.0         3.6          1.4         0.2     setosa
  6            5.4         3.9          1.7         0.4     setosa
  7            4.6         3.4          1.4         0.3     setosa
  8            5.0         3.4          1.5         0.2     setosa
  9            4.4         2.9          1.4         0.2     setosa
  10           4.9         3.1          1.5         0.1     setosa
  11           5.4         3.7          1.5         0.2     setosa
  12           4.8         3.4          1.6         0.2     setosa
  13           4.8         3.0          1.4         0.1     setosa
  14           4.3         3.0          1.1         0.1     setosa
  15           5.8         4.0          1.2         0.2     setosa
  16           5.7         4.4          1.5         0.4     setosa
  17           5.4         3.9          1.3         0.4     setosa
  18           5.1         3.5          1.4         0.3     setosa
  19           5.7         3.8          1.7         0.3     setosa
  20           5.1         3.8          1.5         0.3     setosa
  21           5.4         3.4          1.7         0.2     setosa
  22           5.1         3.7          1.5         0.4     setosa
  23           4.6         3.6          1.0         0.2     setosa
  24           5.1         3.3          1.7         0.5     setosa
  25           4.8         3.4          1.9         0.2     setosa
  26           5.0         3.0          1.6         0.2     setosa
  27           5.0         3.4          1.6         0.4     setosa
  28           5.2         3.5          1.5         0.2     setosa
  29           5.2         3.4          1.4         0.2     setosa
  30           4.7         3.2          1.6         0.2     setosa
  31           4.8         3.1          1.6         0.2     setosa
  32           5.4         3.4          1.5         0.4     setosa
  33           5.2         4.1          1.5         0.1     setosa
  34           5.5         4.2          1.4         0.2     setosa
  35           4.9         3.1          1.5         0.2     setosa
  36           5.0         3.2          1.2         0.2     setosa
  37           5.5         3.5          1.3         0.2     setosa
  38           4.9         3.6          1.4         0.1     setosa
  39           4.4         3.0          1.3         0.2     setosa
  40           5.1         3.4          1.5         0.2     setosa
  41           5.0         3.5          1.3         0.3     setosa
  42           4.5         2.3          1.3         0.3     setosa
  43           4.4         3.2          1.3         0.2     setosa
  44           5.0         3.5          1.6         0.6     setosa
  45           5.1         3.8          1.9         0.4     setosa
  46           4.8         3.0          1.4         0.3     setosa
  47           5.1         3.8          1.6         0.2     setosa
  48           4.6         3.2          1.4         0.2     setosa
  49           5.3         3.7          1.5         0.2     setosa
  50           5.0         3.3          1.4         0.2     setosa
  51           7.0         3.2          4.7         1.4 versicolor
  52           6.4         3.2          4.5         1.5 versicolor
  53           6.9         3.1          4.9         1.5 versicolor
  54           5.5         2.3          4.0         1.3 versicolor
  55           6.5         2.8          4.6         1.5 versicolor
  56           5.7         2.8          4.5         1.3 versicolor
  57           6.3         3.3          4.7         1.6 versicolor
  58           4.9         2.4          3.3         1.0 versicolor
  59           6.6         2.9          4.6         1.3 versicolor
  60           5.2         2.7          3.9         1.4 versicolor
  61           5.0         2.0          3.5         1.0 versicolor
  62           5.9         3.0          4.2         1.5 versicolor
  63           6.0         2.2          4.0         1.0 versicolor
  64           6.1         2.9          4.7         1.4 versicolor
  65           5.6         2.9          3.6         1.3 versicolor
  66           6.7         3.1          4.4         1.4 versicolor
  67           5.6         3.0          4.5         1.5 versicolor
  68           5.8         2.7          4.1         1.0 versicolor
  69           6.2         2.2          4.5         1.5 versicolor
  70           5.6         2.5          3.9         1.1 versicolor
  71           5.9         3.2          4.8         1.8 versicolor
  72           6.1         2.8          4.0         1.3 versicolor
  73           6.3         2.5          4.9         1.5 versicolor
  74           6.1         2.8          4.7         1.2 versicolor
  75           6.4         2.9          4.3         1.3 versicolor
  76           6.6         3.0          4.4         1.4 versicolor
  77           6.8         2.8          4.8         1.4 versicolor
  78           6.7         3.0          5.0         1.7 versicolor
  79           6.0         2.9          4.5         1.5 versicolor
  80           5.7         2.6          3.5         1.0 versicolor
  81           5.5         2.4          3.8         1.1 versicolor
  82           5.5         2.4          3.7         1.0 versicolor
  83           5.8         2.7          3.9         1.2 versicolor
  84           6.0         2.7          5.1         1.6 versicolor
  85           5.4         3.0          4.5         1.5 versicolor
  86           6.0         3.4          4.5         1.6 versicolor
  87           6.7         3.1          4.7         1.5 versicolor
  88           6.3         2.3          4.4         1.3 versicolor
  89           5.6         3.0          4.1         1.3 versicolor
  90           5.5         2.5          4.0         1.3 versicolor
  91           5.5         2.6          4.4         1.2 versicolor
  92           6.1         3.0          4.6         1.4 versicolor
  93           5.8         2.6          4.0         1.2 versicolor
  94           5.0         2.3          3.3         1.0 versicolor
  95           5.6         2.7          4.2         1.3 versicolor
  96           5.7         3.0          4.2         1.2 versicolor
  97           5.7         2.9          4.2         1.3 versicolor
  98           6.2         2.9          4.3         1.3 versicolor
  99           5.1         2.5          3.0         1.1 versicolor
  100          5.7         2.8          4.1         1.3 versicolor
  101          6.3         3.3          6.0         2.5  virginica
  102          5.8         2.7          5.1         1.9  virginica
  103          7.1         3.0          5.9         2.1  virginica
  104          6.3         2.9          5.6         1.8  virginica
  105          6.5         3.0          5.8         2.2  virginica
  106          7.6         3.0          6.6         2.1  virginica
  107          4.9         2.5          4.5         1.7  virginica
  108          7.3         2.9          6.3         1.8  virginica
  109          6.7         2.5          5.8         1.8  virginica
  110          7.2         3.6          6.1         2.5  virginica
  111          6.5         3.2          5.1         2.0  virginica
  112          6.4         2.7          5.3         1.9  virginica
  113          6.8         3.0          5.5         2.1  virginica
  114          5.7         2.5          5.0         2.0  virginica
  115          5.8         2.8          5.1         2.4  virginica
  116          6.4         3.2          5.3         2.3  virginica
  117          6.5         3.0          5.5         1.8  virginica
  118          7.7         3.8          6.7         2.2  virginica
  119          7.7         2.6          6.9         2.3  virginica
  120          6.0         2.2          5.0         1.5  virginica
  121          6.9         3.2          5.7         2.3  virginica
  122          5.6         2.8          4.9         2.0  virginica
  123          7.7         2.8          6.7         2.0  virginica
  124          6.3         2.7          4.9         1.8  virginica
  125          6.7         3.3          5.7         2.1  virginica
  126          7.2         3.2          6.0         1.8  virginica
  127          6.2         2.8          4.8         1.8  virginica
  128          6.1         3.0          4.9         1.8  virginica
  129          6.4         2.8          5.6         2.1  virginica
  130          7.2         3.0          5.8         1.6  virginica
  131          7.4         2.8          6.1         1.9  virginica
  132          7.9         3.8          6.4         2.0  virginica
  133          6.4         2.8          5.6         2.2  virginica
  134          6.3         2.8          5.1         1.5  virginica
  135          6.1         2.6          5.6         1.4  virginica
  136          7.7         3.0          6.1         2.3  virginica
  137          6.3         3.4          5.6         2.4  virginica
  138          6.4         3.1          5.5         1.8  virginica
  139          6.0         3.0          4.8         1.8  virginica
  140          6.9         3.1          5.4         2.1  virginica
  141          6.7         3.1          5.6         2.4  virginica
  142          6.9         3.1          5.1         2.3  virginica
  143          5.8         2.7          5.1         1.9  virginica
  144          6.8         3.2          5.9         2.3  virginica
  145          6.7         3.3          5.7         2.5  virginica
  146          6.7         3.0          5.2         2.3  virginica
  147          6.3         2.5          5.0         1.9  virginica
  148          6.5         3.0          5.2         2.0  virginica
  149          6.2         3.4          5.4         2.3  virginica
  150          5.9         3.0          5.1         1.8  virginica
  > X = iris[,!names(iris) %in% "Species"]
  > Y = iris[,"Species"]
  > as.numeric(Y)
    [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
   [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
   [75] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3
  [112] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
  [149] 3 3
  > rf.42 = randomForest(X,Y,keep.forest=T,replace=F,keep.inbag=T,samp=15,ntree=100)
  > ff.42 = forestFloor(rf.42,X,calc_np = F,bootstrapFC = TRUE)
  > 
  > #test accuracy of feature contributions
  > #y_hat_OOB = row sum FC + Y_grandMean
  > FCc = t(t(apply(ff.42$FCarray,c(1,3),sum))+as.vector(table(Y)/length(Y)))
  > FC.residuals = FCc-predict(rf.42,type="prob")
  > if(max(abs(FC.residuals))>1E-12) stop(
  +   paste0("When testing if:  y_hat_OOB = row sum FCmatrix + Y_grandMean
  +          one/some FCs error exceeds allowed 1e-12, found.error=",max(abs(FC.residuals)))
  + )
  > 
  > Xtest = iris[1:50,] #copy
  > Xtest = Xtest[,-5] #drop Species
  > Xtest[1:4] = lapply(iris[1:4],sample,50) #random resample 50 samples
  > 
  > 
  > #test same results are reached with Xtest
  > ff.43 = forestFloor(rf.42,X,Xtest,bootstrapFC = T)
  > if(max(abs(ff.43$FCarray[ff.43$isTrain,,]-ff.42$FCarray)) > 1E-12) stop(
  +   "forestFloor with/without Xtest gives different feature contributions"
  + )
  > plot(ff.43,speedup_GOF = TRUE,plotTest = F)
  > 
  > 
  > pred = sapply(1:3,function(i) apply(ff.42$FCarray[,,i],1,sum))+1/3
  > rfPred = predict(rf.42,type="vote",norm.votes=T)
  > rfPred[is.nan(rfPred)] = 1/3
  > if(cor(as.vector(rfPred),as.vector(pred))^2<0.99) stop("fail testMultiClass")
  > attributes(ff.42)
  $names
  [1] "X"           "Y"           "importance"  "imp_ind"     "FCarray"    
  [6] "sumOfInbags" "isTrain"    
  
  $class
  [1] "forestFloor_multiClass"
  
  > args(forestFloor:::plot.forestFloor_multiClass)
  function (x, plot_seq = NULL, label.seq = NULL, plotTest = NULL, 
      limitY = TRUE, col = NULL, colLists = NULL, orderByImportance = TRUE, 
      fig.columns = NULL, plot_GOF = TRUE, GOF_args = list(), speedup_GOF = TRUE, 
      jitter_these_cols = NULL, jitter.factor = NULL, ...) 
  NULL
  > plot(ff.42,plot_GOF=T,cex=.7,
  +      colLists=list("#FF0000A5",
  +                    "#00FF0050",
  +                    "#0000FF35")
  +      )
  > 
  > plot(ff.43,plot_GOF=T,cex=.7,
  +      colLists=list("#FF0000A5",
  +                    "#00FF0050",
  +                    "#0000FF35")
  + )
  > 
  > #use col interface
  > plot(ff.43,plot_GOF=T,cex=.7,
  +      col=list("#FF0000A5","#00FF0050","#0000FF35") #one colour per class
  + )
  > 
  > plot(ff.43,plot_GOF=T,cex=.7,
  +      col=c("#FF0000A5","#00FF0050","#0000FF35") #one colour per class
  + )
  > 
  > 
  > #try to alter std par
  > plot(ff.42,plot_GOF=T,cex=.7,
  +      colLists=list("#FF0000A5",
  +                    "#00FF0050",
  +                    "#0000FF35"),
  +      mfrow=c(4,3)
  + )
  > 
  > 
  > show3d(ff.42,1:2,1:2,plot_GOF=T)
  > show3d(ff.42,1:2,1,plot_GOF=T)#test plotting only one feature contribution
  > 
  > 
  > #plot all effect 2D only
  > pars = plot_simplex3(ff.42,Xi=c(1:3),restore_par=F,zoom.fit=NULL,var.col=NULL,fig.cols=2,fig.rows=1,
  +                fig3d=F,includeTotal=T,auto.alpha=.4,set_pars=T)
  > pars = plot_simplex3(ff.42,Xi=0,restore_par=F,zoom.fit=NULL,var.col=alist(alpha=.3,cols=1:4),
  +                fig3d=F,includeTotal=T,auto.alpha=.8,set_pars=F)
   ----------- FAILURE REPORT -------------- 
   --- failure: the condition has length > 1 ---
   --- srcref --- 
  : 
   --- package (from environment) --- 
  forestFloor
   --- call from context --- 
  box.outliers(prcomp(sel.colM)$x[, 1:max.df], limit = Inf)
   --- call from argument --- 
  if (class(x) == "data.frame") {
      sx = as.data.frame(sx, row.names = row.names(x))
      names(sx) = names(x)
  }
   --- R stacktrace ---
  where 1: box.outliers(prcomp(sel.colM)$x[, 1:max.df], limit = Inf)
  where 2: (function (ff, cols = NULL, orderByImportance = NULL, plotTest = NULL, 
      X.matrix = TRUE, hue = NULL, saturation = NULL, brightness = NULL, 
      hue.range = NULL, sat.range = NULL, bri.range = NULL, alpha = NULL, 
      RGB = NULL, byResiduals = FALSE, max.df = 3, imp.weight = NULL, 
      imp.exp = 1, outlier.lim = 3, RGB.exp = NULL) 
  {
      if (!X.matrix) 
          if (class(ff) == "forestFloor_multiClass") 
              stop("cannot colour by feature contributions for object of class\n         'forestFloor_multiClass'. Set X.matrix=TRUE")
      ib <- function(x, low, high) (x - low) * (high - x) > 0
      span <- function(x, mid, width) if (min(x) != max(x)) {
          ((x - min(x))/(max(x) - min(x)) - 0.5) * width + mid
      }
      else {
          x[] = mid
      }
      auto.range = function(level, low = 0, high = 1) abs(min(level - 
          low, high - level)) * 2
      contain = function(x, low = 0, high = 1) {
          x[x > high] = high
          x[x < low] = low
          x
      }
      if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
          plotThese = checkPlotTest(plotTest, ff$isTrain)
          if (!(all(plotThese))) {
              if (class(ff) == "forestFloor_multiClass") {
                  ff$FCarray = ff$FCarray[plotThese, , ]
              }
              else {
                  if (class(ff) == "forestFloor_regression") {
                    ff$FCmatrix = ff$FCmatrix[plotThese, ]
                  }
              }
              ff$Y = ff$Y[plotThese]
              ff$X = ff$X[plotThese, ]
          }
      }
      if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
          if (byResiduals) {
              if (is.null(ff$FCfit)) {
                  print("no $FCfit found, computing tempoary LOO-kNN-gaussion fit to main affect")
                  print("use ff = convolute_ff(ff) to compute a fixed fit")
                  ff = convolute_ff(ff)
              }
              colM = ff$FCmatrix - ff$FCfit
          }
          else {
              if (X.matrix) 
                  colM = ff$X
              else colM = ff$FCmatrix
          }
          if (is.null(imp.weight)) 
              imp.weight = TRUE
          if (is.null(orderByImportance)) 
              orderByImportance = TRUE
      }
      else {
          colM = ff
          if (is.null(imp.weight)) 
              imp.weight = FALSE
          if (is.null(orderByImportance)) 
              orderByImportance = FALSE
      }
      if (orderByImportance) 
          if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
              colM = colM[, ff$imp_ind]
          }
          else {
              warning("orderByImportance=TRUE takes no effect for non 'forestFloor'-class. As if set to NULL or FALSE...")
          }
      if (!class(colM) %in% c("data.frame", "matrix")) {
          tryCatch({
              colM = matrix(colM, ncol = 1)
          }, error = function(e) stop(paste("input ff was neither data.frame or matrix and \ncould not be coerced to matrix:", 
              e$message)))
      }
      colM = data.frame(colM)
      if (is.null(cols)) 
          cols = 1:dim(colM)[2]
      if (length(cols) < 1 || !is.numeric(cols) || any(!cols %in% 
          1:dim(colM)[2])) {
          stop("no cols selected or is not integer/numeric or wrong coloumns")
      }
      sel.colM = data.frame(colM[, cols])
      sel.cols = 1:length(cols)
      if (is.null(RGB)) 
          if (length(cols) == 1) 
              RGB = TRUE
          else RGB = FALSE
      if (!RGB) {
          if (is.null(saturation)) 
              saturation = 0.85
          if (is.null(brightness)) 
              brightness = 0.75
          if (is.null(hue)) 
              hue = 0.25
      }
      else {
          if (is.null(saturation)) 
              saturation = 1
          if (is.null(brightness)) 
              brightness = 0.75
          if (is.null(hue)) 
              hue = 0.66
          if (is.null(RGB.exp)) 
              RGB.exp = 1.2
          if (is.null(hue.range)) 
              hue.range = 2
      }
      as.numeric.factor <- function(x, rearrange = TRUE) {
          if (is.numeric(x)) 
              return(x)
          if (rearrange) 
              x = match(x, levels(droplevels(x)))
          else x = match(x, levels(x))
          return(x)
      }
      for (i in 1:dim(sel.colM)[2]) {
          if (is.factor(sel.colM[, i])) {
              this.fac = as.numeric.factor(sel.colM[, i])
              sel.colM[, i] = this.fac
          }
          if (is.character(sel.colM[, i])) 
              sel.colM[, i] = as.numeric(sel.colM[, i])
      }
      sel.colM = box.outliers(sel.colM, limit = outlier.lim)
      if (imp.weight && length(cols) > 1) {
          if (class(ff) %in% c("forestFloor_regression", "forestFloor_multiClass")) {
              sel.imp = ff$importance[cols]
              non.negative.imp = sel.imp + min(sel.imp)
              sumnorm.imp = non.negative.imp/sum(non.negative.imp)
              exp.imp = sumnorm.imp^imp.exp
              impM = t(replicate(dim(colM)[1], exp.imp))
              sel.colM = sel.colM * impM
              sel.colM = sel.colM/max(sel.colM)
          }
          else {
              warning("importance weighting only possible for class 'forestFloor'")
          }
      }
      if (any(!c(class(hue), class(saturation), class(brightness)) %in% 
          c("numeric", "integer"))) {
          stop("hue, saturation and brightness must be of class numeric or integer")
      }
      hue = hue - floor(hue)
      saturation = max(min(saturation, 1), 0)
      brightness = max(min(brightness, 1), 0)
      if (RGB == TRUE) {
          if (is.null(bri.range)) 
              bri.range = 0.05
          if (is.null(alpha)) 
              alpha = 0.7
          len.colM = box.outliers(sel.colM, limit = Inf)
          if (dim(len.colM)[2] == 1) 
              nX = as.numeric(len.colM[, 1])
          else nX = as.numeric(apply(len.colM, 1, mean))
          hsvcol = t(sapply(nX, function(x) rgb2hsv(x^RGB.exp, 
              1 - x^RGB.exp - (1 - x)^RGB.exp, (1 - x)^RGB.exp)))
          hue.vec = hsvcol[, 1] * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - floor(hue.vec[hue.vec > 
              1])
          hsvcol[, 1] = hue.vec
          sat.range = auto.range(saturation)
          hsvcol[, 2] = span(hsvcol[, 2], saturation, sat.range)
          hsvcol[, 2] = contain(hsvcol[, 2])
          bri.range = auto.range(brightness)
          hsvcol[, 3] = span(hsvcol[, 3], brightness, bri.range)
          hsvcol[, 3] = contain(hsvcol[, 3])
          colours = apply(hsvcol, 1, function(x) hsv(x[1], x[2], 
              x[3], alpha = alpha))
          return(colours)
      }
      col.df = length(cols)
      if (!max.df %in% c(1, 2, 3)) 
          stop("fcol input 'max.df' must be set to either 1, 2 or 3")
      if (col.df > max.df) {
          len.colM = box.outliers(prcomp(sel.colM)$x[, 1:max.df], 
              limit = Inf)
          col.df = max.df
      }
      else {
          len.colM = box.outliers(sel.colM, limit = Inf)
      }
      if (is.null(hue.range)) {
          if (col.df == 1) 
              hue.range = 0.85
          if (col.df == 2) 
              hue.range = 1
          if (col.df == 3) 
              hue.range = 1
      }
      if (is.null(sat.range)) {
          if (col.df == 1) 
              sat.range = "not used"
          if (col.df == 2) 
              sat.range = auto.range(saturation)
          if (col.df == 3) 
              sat.range = auto.range(saturation)
      }
      if (is.null(bri.range)) {
          if (col.df == 1) 
              bri.range = "not used"
          if (col.df == 2) 
              bri.range = "not used"
          if (col.df == 3) 
              bri.range = auto.range(brightness)
      }
      if (is.null(alpha)) 
          alpha = min(1, 400/dim(len.colM)[1])
      if (col.df == 1) {
          hue.vec = as.numeric(len.colM[, 1]) * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - floor(hue.vec[hue.vec > 
              1])
          colours = hsv(h = hue.vec, s = saturation, v = brightness, 
              alpha = alpha)
      }
      if (col.df == 2) {
          hsvcol = t(rgb2hsv(len.colM[, 1], len.colM[, 2], 1 - 
              apply(len.colM, 1, mean)))
          hue.vec = hsvcol[, 1] * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - 1
          hsvcol[, 1] = hue.vec
          hsvcol[, 2] = ((len.colM[, 1] - mean(len.colM[, 1]))^2 + 
              (len.colM[, 2] - mean(len.colM[, 2]))^2)^sat.range * 
              saturation
          hsvcol[, 2] = hsvcol[, 2]/max(hsvcol[, 2])
          hsvcol[, 3] = brightness
          colours = hsv(hsvcol[, 1], hsvcol[, 2], hsvcol[, 3], 
              alpha = alpha)
      }
      if (col.df == 3) {
          hsvcol = t(rgb2hsv(len.colM[, 1], len.colM[, 2], len.colM[, 
              3]))
          hue.vec = hsvcol[, 1] * hue.range + hue
          hue.vec[hue.vec > 1] = hue.vec[hue.vec > 1] - 1
          hsvcol[, 1] = hue.vec
          span.sat = span(hsvcol[, 2], saturation, sat.range)
          hsvcol[, 2] = contain(span.sat)
          mean.bri = apply(len.colM, 1, mean)
          span.bri = span(mean.bri, brightness, bri.range)
          hsvcol[, 3] = contain(span.bri)
          colours = hsv(hsvcol[, 1], hsvcol[, 2], hsvcol[, 3], 
              alpha = alpha)
      }
      return(colours)
  })(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6, 5, 5.4, 4.6, 5, 
  4.4, 4.9, 5.4, 4.8, 4.8, 4.3, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 
  5.1, 4.6, 5.1, 4.8, 5, 5, 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 
  4.9, 5, 5.5, 4.9, 4.4, 5.1, 5, 4.5, 4.4, 5, 5.1, 4.8, 5.1, 4.6, 
  5.3, 5, 7, 6.4, 6.9, 5.5, 6.5, 5.7, 6.3, 4.9, 6.6, 5.2, 5, 5.9, 
  6, 6.1, 5.6, 6.7, 5.6, 5.8, 6.2, 5.6, 5.9, 6.1, 6.3, 6.1, 6.4, 
  6.6, 6.8, 6.7, 6, 5.7, 5.5, 5.5, 5.8, 6, 5.4, 6, 6.7, 6.3, 5.6, 
  5.5, 5.5, 6.1, 5.8, 5, 5.6, 5.7, 5.7, 6.2, 5.1, 5.7, 6.3, 5.8, 
  7.1, 6.3, 6.5, 7.6, 4.9, 7.3, 6.7, 7.2, 6.5, 6.4, 6.8, 5.7, 5.8, 
  6.4, 6.5, 7.7, 7.7, 6, 6.9, 5.6, 7.7, 6.3, 6.7, 7.2, 6.2, 6.1, 
  6.4, 7.2, 7.4, 7.9, 6.4, 6.3, 6.1, 7.7, 6.3, 6.4, 6, 6.9, 6.7, 
  6.9, 5.8, 6.8, 6.7, 6.7, 6.3, 6.5, 6.2, 5.9), Sepal.Width = c(3.5, 
  3, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3, 3, 4, 
  4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3, 3.4, 3.5, 
  3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3, 3.4, 3.5, 
  2.3, 3.2, 3.5, 3.8, 3, 3.8, 3.2, 3.7, 3.3, 3.2, 3.2, 3.1, 2.3, 
  2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2, 3, 2.2, 2.9, 2.9, 3.1, 3, 2.7, 
  2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3, 2.8, 3, 2.9, 2.6, 2.4, 
  2.4, 2.7, 2.7, 3, 3.4, 3.1, 2.3, 3, 2.5, 2.6, 3, 2.6, 2.3, 2.7, 
  3, 2.9, 2.9, 2.5, 2.8, 3.3, 2.7, 3, 2.9, 3, 3, 2.5, 2.9, 2.5, 
  3.6, 3.2, 2.7, 3, 2.5, 2.8, 3.2, 3, 3.8, 2.6, 2.2, 3.2, 2.8, 
  2.8, 2.7, 3.3, 3.2, 2.8, 3, 2.8, 3, 2.8, 3.8, 2.8, 2.8, 2.6, 
  3, 3.4, 3.1, 3, 3.1, 3.1, 3.1, 2.7, 3.2, 3.3, 3, 2.5, 3, 3.4, 
  3), Petal.Length = c(1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 
  1.4, 1.5, 1.5, 1.6, 1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 
  1.5, 1, 1.7, 1.9, 1.6, 1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 
  1.5, 1.2, 1.3, 1.4, 1.3, 1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 
  1.4, 1.5, 1.4, 4.7, 4.5, 4.9, 4, 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 
  3.5, 4.2, 4, 4.7, 3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4, 4.9, 
  4.7, 4.3, 4.4, 4.8, 5, 4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 
  4.7, 4.4, 4.1, 4, 4.4, 4.6, 4, 3.3, 4.2, 4.2, 4.2, 4.3, 3, 4.1, 
  6, 5.1, 5.9, 5.6, 5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3, 5.5, 
  5, 5.1, 5.3, 5.5, 6.7, 6.9, 5, 5.7, 4.9, 6.7, 4.9, 5.7, 6, 4.8, 
  4.9, 5.6, 5.8, 6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 
  5.6, 5.1, 5.1, 5.9, 5.7, 5.2, 5, 5.2, 5.4, 5.1), Petal.Width = c(0.2, 
  0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 
  0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 
  0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 
  0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2, 1.4, 1.5, 1.5, 
  1.3, 1.5, 1.3, 1.6, 1, 1.3, 1.4, 1, 1.5, 1, 1.4, 1.3, 1.4, 1.5, 
  1, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1, 
  1.1, 1, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 
  1, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3, 2.5, 1.9, 2.1, 1.8, 2.2, 2.1, 
  1.7, 1.8, 1.8, 2.5, 2, 1.9, 2.1, 2, 2.4, 2.3, 1.8, 2.2, 2.3, 
  1.5, 2.3, 2, 2, 1.8, 2.1, 1.8, 1.8, 1.8, 2.1, 1.6, 1.9, 2, 2.2, 
  1.5, 1.4, 2.3, 2.4, 1.8, 1.8, 2.1, 2.4, 2.3, 1.9, 2.3, 2.5, 2.3, 
  1.9, 2, 2.3, 1.8)), 0, alpha = 0.3, cols = 1:4)
  where 3: do.call(fcol, c(list(ff$X, i), var.col))
  where 4: plot.xy(xy.coords(x, y), type = type, ...)
  where 5: points.default(apply(xd1 * t(FC[, ]), 2, sum) + cent2[1], apply(xd2 * 
      t(FC[, ]), 2, sum) + cent2[2], cex = 0.3, col = if (Col[1] == 
      "var.col") do.call(fcol, c(list(ff$X, i), var.col)) else Col)
  where 6: points(apply(xd1 * t(FC[, ]), 2, sum) + cent2[1], apply(xd2 * 
      t(FC[, ]), 2, sum) + cent2[2], cex = 0.3, col = if (Col[1] == 
      "var.col") do.call(fcol, c(list(ff$X, i), var.col)) else Col)
  where 7: plot_simplex3(ff.42, Xi = 0, restore_par = F, zoom.fit = NULL, 
      var.col = alist(alpha = 0.3, cols = 1:4), fig3d = F, includeTotal = T, 
      auto.alpha = 0.8, set_pars = F)
  
   --- value of length: 2 type: logical ---
  [1] FALSE FALSE
   --- function from context --- 
  function (x, limit = 1.5, normalize = TRUE) 
  {
      sx = scale(x)
      if (limit != FALSE) {
          sx[sx > limit] = limit
          sx[-sx > limit] = -limit
      }
      if (normalize) {
          sx.span = max(sx) - min(sx)
          sx = sx - min(sx)
          sx = sx/sx.span
      }
      else {
          obs = attributes(sx)$dim[1]
          if (dim(sx)[2] > 1) {
              sx = sx * t(replicate(obs, attributes(sx)$"scaled:scale")) + 
                  t(replicate(obs, attributes(sx)$"scaled:center"))
          }
          else {
              sx = sx * attributes(sx)$"scaled:scale" + attributes(sx)$"scaled:center"
          }
      }
      if (class(x) == "data.frame") {
          sx = as.data.frame(sx, row.names = row.names(x))
          names(sx) = names(x)
      }
      return(sx)
  }
  <bytecode: 0x561264cbf120>
  <environment: namespace:forestFloor>
   --- function search by body ---
  Function box.outliers in namespace forestFloor has this body.
   ----------- END OF FAILURE REPORT -------------- 
  Fatal error: the condition has length > 1