File: OptPath_plotEAF.R

package info (click to toggle)
r-cran-paramhelpers 1.12-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 984 kB
  • sloc: ansic: 260; sh: 13; makefile: 2
file content (91 lines) | stat: -rw-r--r-- 3,533 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#' @title Plots attainment functions for data stored in multiple OptPaths.
#'
#' @description
#' Can be used to plot OptPaths where information for bi-objective
#' evaluation was logged for repeated runs of different algorithmic runs.
#' Pretty directly calls \code{\link[eaf]{eafplot}}.
#'
#' @param opt.paths [\code{list}]\cr
#'   List of list of \code{OptPath} objects. First index is the algorithm / major variation
#'   in the experiment, second index is the index of the replicated run.
#' @param xlim [\code{numeric(2)}]\cr
#'   The x limits (x1, x2) of the plot.
#' @param ylim [\code{numeric(2)}]\cr
#'   The y limits (y1, y2) of the plot.
#' @param ... [any]\cr
#'   Passed on to \code{\link[eaf]{eafplot}}.
#' @note
#'   We changed the defaults of \code{\link[eaf]{eafplot}} in the following way:
#'   The axis are labeled by \code{y.names}, colors are set to our favorite grey
#'   values and linetypes changed, too. With our colors / linetypes default it is
#'   possible to distinguish 6 different algorithms. But this can again be overwritten by the user.
#' @return [\code{data.frame}]
#'   Invisibly returns the data passed to \code{\link[eaf]{eafplot}}.
#' @export
plotEAF = function(opt.paths, xlim = NULL, ylim = NULL, ...) {
  requirePackages("eaf", why = "plotEAF")

  # we need a list of lists with optimization pathes
  assertList(opt.paths, min.len = 1L, types = "list", names = "unique")

  if (!is.null(xlim))
    assertNumeric(xlim, len = 2L)
  if (!is.null(ylim))
    assertNumeric(ylim, len = 2L)

  algos = names(opt.paths)
  y.names = NULL
  minimize = NULL
  data = data.frame()
  for (i in seq_along(algos)) {
    # extract opt path list for current algorithm
    a = algos[i]
    runs = opt.paths[[i]]
    assertList(runs, types = "OptPath", min.len = 1L)

    # combine all fronts for this algo + add algo / repl + do some sanity checks
    fronts = lapply(seq_along(runs), function(j) {
      run = runs[[j]]
      df = as.data.frame(getOptPathParetoFront(run))
      cns = colnames(df)
      if (length(cns) != 2L) {
        stopf("Must always have 2 objectives in opt path. But found: %i", length(cns))
      }
      if (i == 1L && j == 1L) {
        y.names <<- cns
        minimize <<- run$minimize
      }
      if (!all(y.names == cns)) {
        stopf("Must always have the same 2 objectives in opt path: %s (first ones taken). But found here: %s",
          collapse(y.names), collapse(cns))
      }
      if (!all(minimize == run$minimize)) {
        stopf("Must always have the same 'minimize' settings for objectives in opt path: %s (first one taken).
          But found here: %s", collapse(minimize), collapse(run$minimize))
      }
      # add column for algorithm and replication
      cbind(df, .algo = a, .repl = j)
    })
    fronts = do.call(rbind, fronts)
    data = rbind(data, fronts)
  }
  yn1 = y.names[1L]
  yn2 = y.names[2L]
  # build parameter list for eafplot function
  f = as.formula(sprintf("%s + %s ~ .repl", yn1, yn2))
  defaults = list(
    xlab = yn1, ylab = yn2,
    percentiles = 50,
    col = c("darkgrey", "darkgrey", "darkgrey", "black", "black", "black"),
    lty =  c("solid", "dashed", "dotdash", "solid", "dashed", "dotdash")
  )
  args = list(...)
  args = insert(defaults, args)
  args$data = data
  args$groups = quote(.algo)
  args$maximise = !minimize
  args$xlim = xlim
  args$ylim = ylim
  do.call(eaf::eafplot, c(list(f), args)) # due to not so good programming in eafplot the first argument can not be named if it's a formula
  return(data)
}