Nothing
#' Compute empirical attainment function differences
#'
#' Calculate the differences between the empirical attainment functions of two
#' data sets.
#'
#' @param x,y `matrix`|`data.frame()`\cr Data frames corresponding to the input data of
#' left and right sides, respectively. Each data frame has at least three
#' columns, the last one is the set of each point. See also
#' [read_datasets()].
#'
#' @param intervals `integer(1)`\cr The absolute range of the differences
#' \eqn{[0, 1]} is partitioned into the number of intervals provided.
#'
#' @inheritParams is_nondominated
#'
#' @param rectangles `logical(1)`\cr If TRUE, the output is in the form of rectangles of the same color.
#'
#' @details
#' This function calculates the differences between the EAFs of two
#' data sets.
#'
#' @return With `rectangle=FALSE`, a `data.frame` containing points where there
#' is a transition in the value of the EAF differences. With
#' `rectangle=TRUE`, a `matrix` where the first 4 columns give the
#' coordinates of two corners of each rectangle. In both cases, the last
#' column gives the difference in terms of sets in `x` minus sets in `y` that
#' attain each point (i.e., negative values are differences in favour `y`).
#'
#' @seealso [read_datasets()]
# , [mooplot::eafdiffplot()]
#'
#' @doctest
#' A1 <- read_datasets(text='
#' 3 2
#' 2 3
#'
#' 2.5 1
#' 1 2
#'
#' 1 2
#' ')
#'
#' A2 <- read_datasets(text='
#' 4 2.5
#' 3 3
#' 2.5 3.5
#'
#' 3 3
#' 2.5 3.5
#'
#' 2 1
#' ')
#' d <- eafdiff(A1, A2)
#' @omit
#' str(d)
#' @expect true(is.matrix(.))
#' d
#' @testRaw expect_equal(d,matrix(byrow=TRUE, ncol=3, scan(quiet = TRUE, text='1.0 2.0 2
#' @testRaw 2.0 1.0 -1
#' @testRaw 2.5 1.0 0
#' @testRaw 2.0 2.0 1
#' @testRaw 2.0 3.0 2
#' @testRaw 3.0 2.0 2
#' @testRaw 2.5 3.5 0
#' @testRaw 3.0 3.0 0
#' @testRaw 4.0 2.5 1')))
#'
#' d <- eafdiff(A1, A2, rectangles = TRUE)
#' @omit
#' str(d)
#' d
#' @testRaw expect_equal(d, as.matrix(read.table(header=TRUE, text='
#' @testRaw xmin ymin xmax ymax diff
#' @testRaw 2.0 1.0 2.5 2.0 -1
#' @testRaw 1.0 2.0 2.0 Inf 2
#' @testRaw 2.5 1.0 Inf 2.0 0
#' @testRaw 2.0 2.0 3.0 3.0 1
#' @testRaw 2.0 3.5 2.5 Inf 2
#' @testRaw 2.0 3.0 3.0 3.5 2
#' @testRaw 3.0 2.5 4.0 3.0 2
#' @testRaw 3.0 2.0 Inf 2.5 2
#' @testRaw 4.0 2.5 Inf 3.0 1')))
#'@concept eaf
#'@export
eafdiff <- function(x, y, intervals = NULL, maximise = FALSE, rectangles = FALSE)
{
stopifnot(ncol(x) == ncol(y))
sets_x <- x[, ncol(x)]
if (anyNA(sets_x)) stop("'sets' must have only non-NA numerical values")
cumsizes_x <- cumsum(unique_counts(sets_x))
# The C code expects points within a set to be contiguous.
x <- as_double_matrix(x[order(sets_x) , -ncol(x), drop=FALSE])
sets_y <- y[, ncol(y)]
if (anyNA(sets_y)) stop("'sets' must have only non-NA numerical values")
cumsizes_y <- cumsum(unique_counts(sets_y))
# The C code expects points within a set to be contiguous.
y <- as_double_matrix(y[order(sets_y), -ncol(y), drop=FALSE])
nsets <- length(cumsizes_x) + length(cumsizes_y)
if (is.null(intervals)) {
# Default is nsets / 2
intervals <- nsets / 2.0
} else {
stopifnot(length(intervals) == 1L)
intervals <- min(intervals, nsets / 2.0)
}
maximise <- as.logical(maximise)
if (any(maximise)) {
x <- transform_maximise(x, maximise)
y <- transform_maximise(y, maximise)
}
DIFF <- compute_eafdiff_call(x, y, cumsizes_x, cumsizes_y,
intervals = intervals, ret = if (rectangles) "rectangles" else "points")
# FIXME: We should remove duplicated rows in C code.
# FIXME: Check that we do not generate duplicated nor overlapping rectangles
# with different colors. That would be a bug.
DIFF <- DIFF[!duplicated(DIFF),]
if (any(maximise)) {
if (rectangles && length(maximise) != 1L)
maximise <- c(maximise, maximise)
DIFF[, -ncol(DIFF)] <- transform_maximise(DIFF[, -ncol(DIFF), drop=FALSE], maximise)
}
# Undo previous transformation
## if (any(maximise)) {
## DIFF[,-ncol(x)] <- transform_maximise(x[, -ncol(x), drop=FALSE], maximise)
## }
DIFF
}
#' Same as [eafdiff()] but performs no checks and does not transform the input
#' or the output. This function should be used by other packages that want to
#' avoid redundant checks and transformations.
#'
#' @seealso [as_double_matrix()] [transform_maximise()]
#' @inherit eafdiff title params return
#' @param cumsizes_x,cumsizes_y Cumulative size of the different sets of points in `x` and `y`.
#' @param ret (`"points"|"rectangles"|"polygons"`)\cr The format of the returned EAF differences.
#' @concept eaf
#' @export
compute_eafdiff_call <- function(x, y, cumsizes_x, cumsizes_y, intervals, ret)
{
x <- cbind(t(x), t(y))
cumsizes <- c(cumsizes_x, cumsizes_x[length(cumsizes_x)] + cumsizes_y)
intervals <- as.integer(intervals)
switch(ret,
rectangles = .Call(compute_eafdiff_rectangles_C, x, cumsizes, intervals),
polygons = .Call(compute_eafdiff_polygon_C, x, cumsizes, intervals),
points = .Call(compute_eafdiff_C, x, cumsizes, intervals))
}
compute_eafdiff <- function(x, y, sets_x, sets_y, intervals)
compute_eafdiff_call(x, y, cumsum(unique_counts(sets_x)), cumsum(unique_counts(sets_y)), intervals, ret = "points")
# FIXME: The default intervals should be nsets / 2
compute_eafdiff_rectangles <- function(x, y, sets_x, sets_y, intervals)
compute_eafdiff_call(x, y, cumsum(unique_counts(sets_x)), cumsum(unique_counts(sets_y)), intervals, ret = "rectangles")
# FIXME: The default intervals should be nsets / 2
compute_eafdiff_polygon <- function(x, y, sets_x, sets_y, intervals)
compute_eafdiff_call(x, y, cumsum(unique_counts(sets_x)), cumsum(unique_counts(sets_y)), intervals, ret = "polygons")
## compute_eafdiff <- function(data, intervals)
## {
## DIFF <- compute_eafdiff_call(data[,c(1L,2L), drop=FALSE], sets = data[,3L], intervals = intervals)
## #print(DIFF)
## # FIXME: Do this computation in C code. See compute_eafdiff_area_C
## setcol <- ncol(data)
## eafval <- DIFF[, setcol]
## eafdiff <- list(left = unique(DIFF[ eafval >= 1L, , drop=FALSE]),
## right = unique(DIFF[ eafval <= -1L, , drop=FALSE]))
## eafdiff$right[, setcol] <- -eafdiff$right[, setcol]
## eafdiff
## }
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.