Fit Euler diagrams (a generalization of Venn diagrams) using numerical optimization to find exact or approximate solutions to a specification of set relationships. The shape of the diagram may be a circle, an ellipse, an axis-aligned rectangle, or an axis-aligned square.
euler(combinations, ...)# S3 method for default
euler(
combinations,
input = c("disjoint", "union"),
transform = identity,
shape = c("circle", "ellipse", "rectangle", "square", "rotated_rectangle"),
loss = c("sum_squared", "sum_absolute", "sum_absolute_region_error",
"sum_squared_region_error", "max_absolute", "max_squared", "root_mean_squared",
"stress", "diag_error", "log_sum_absolute", "smooth_sum_absolute",
"smooth_sum_absolute_region_error", "smooth_max_absolute", "smooth_max_squared",
"smooth_diag_error", "smooth_log_sum_absolute"),
loss_aggregator = NULL,
complement = NULL,
control = list(),
...
)
# S3 method for data.frame
euler(
combinations,
weights = NULL,
by = NULL,
sep = "_",
factor_names = TRUE,
...
)
# S3 method for matrix
euler(combinations, ...)
# S3 method for table
euler(combinations, ...)
# S3 method for list
euler(combinations, ...)
A list object of class 'euler' with the following parameters.
a data frame of fitted shape parameters. One row per set
with a type column (one of "circle", "ellipse", "rectangle",
"square", "rotated_rectangle"), the center coordinates h and k,
and the shape-specific columns: a, b, phi for ellipses/circles;
width and height for rectangles; side (plus mirrored
width/height) for squares; width, height, and phi (rotation,
in radians) for rotated rectangles. Columns that don't apply to the
chosen shape are NA.
for shape = "circle" and shape = "ellipse" fits,
the legacy 5-column data frame of h, k, a, b, phi. This
slot is deprecated in favour of shapes and is not populated for
rectangle/square fits.
set relationships in the input
set relationships in the solution
residuals
the difference in percentage points between each disjoint subset in the input and the respective area in the output
the largest regionError
normalized residual sums of squares
set relationships as a named numeric vector, matrix, or data.frame (see methods (by class))
arguments passed down to other methods
type of input: disjoint identities
('disjoint') or unions ('union').
a function applied to the areas of the disjoint
(exclusive) regions before fitting. The default, base::identity(), leaves
the areas untouched. A monotone transform such as base::log1p() can keep
small regions legible when set sizes span several orders of magnitude. The
transform is applied to the exclusive regions because those are the
additive atoms the diagram fits to; as a consequence the area of a whole
set or union no longer equals transform() of its size, only the
individual visible regions carry the transformed scale. The function must
return a non-negative, finite value for each region (and for complement,
when given). Has no effect on venn() diagrams, whose geometry is fixed.
geometric shape used in the diagram: one of "circle",
"ellipse", "rectangle", "square", or "rotated_rectangle". The
rotated rectangle is fit with a derivative-free optimizer and is also the
only shape able to draw a true four-set Venn diagram (see venn()).
type of loss to minimize over. The default,
"sum_squared", minimizes the sum of squared errors. The available
options mirror the loss functions exposed by the eunoia Rust crate
that powers the optimizer:
"sum_squared": normalized sum of squared errors (default).
"sum_absolute": normalized sum of absolute errors.
"sum_absolute_region_error": normalized sum of absolute
region errors.
"sum_squared_region_error": normalized sum of squared region
errors.
"max_absolute": normalized maximum absolute error.
"max_squared": normalized maximum squared error.
"root_mean_squared": normalized root-mean-squared error.
"stress": venneuler-style stress.
"diag_error": eulerAPE-style diagError.
"log_sum_absolute": sum of absolute errors on log1p-transformed
areas, which stops large regions from dominating the fit.
"smooth_sum_absolute", "smooth_sum_absolute_region_error",
"smooth_max_absolute", "smooth_max_squared", "smooth_diag_error",
"smooth_log_sum_absolute" --- gradient-friendly (Huber) surrogates of
the corresponding non-smooth losses, controlled by control$loss_eps.
deprecated; use loss directly instead. Pre-1.0
code that combined loss ("square"/"abs"/"region") with
loss_aggregator ("sum"/"max") still works but emits a warning;
the combination is mapped to the equivalent new loss value.
an optional single non-negative number giving the area
of the complement, that is, the universe outside every named set.
When supplied, the fitter jointly optimizes a containing rectangle
together with the diagram shapes so that the area of the rectangle
minus the union of (clipped) shapes matches complement. This is the
classical "everything not in any set" region; see plot.euler() for
how it is rendered. Defaults to NULL (no container; classical
shape-only fit). Not supported for venn().
a list of control parameters.
extraopt: should the global-search fallback optimizer (CMA-ES) kick
in when the primary optimizer's diagError exceeds extraopt_threshold?
The default is TRUE for three-set ellipse fits and FALSE otherwise.
extraopt_threshold: threshold, in terms of diagError, for when
the CMA-ES fallback kicks in. A value of 0 means it will kick in for
an* error; a value of 1 means it will never kick in. Default 0.001.
tolerance: convergence tolerance passed to the underlying solver.
Tighter values give more accurate fits at higher cost. Default 1e-8.
max_sets: maximum number of sets the underlying engine will accept.
Defaults to NULL, which uses the engine's built-in default of 32.
Region masks are stored in a bitset, so values may be raised up to 63
(the absolute hard cap). Going higher is rarely useful in practice
since fully-overlapping diagrams have 2^n - 1 regions.
n_threads: number of threads used to fan out the optimizer's restart
loop. A positive integer pins a private thread pool of that size, while
NULL uses all available cores. This is purely a wall-time knob: the
fitted diagram is identical regardless of the thread count. The default
uses half of the available logical cores (but a single thread under
R CMD check, to respect CRAN's two-core policy). It can be overridden
globally with the eulerr.n_threads option or the EULERR_NUM_THREADS
environment variable, and otherwise honors R's conventional mc.cores
option (or MC_CORES environment variable).
optimizer: the final-layout optimizer. The default, "auto", lets the
engine pick a sensible optimizer for the chosen shape and loss. To force a
particular one, use any of "levenberg_marquardt", "lbfgs",
"nelder_mead", "mads" (mesh-adaptive direct search, derivative-free
and well suited to non-smooth losses), "cma_es", "cma_es_lm", "trf",
or "cma_es_trf".
n_restarts: number of full-pipeline restarts; the lowest-loss result
is kept. Higher values improve the chance of finding the global optimum at
proportionally higher cost. NULL (the default) lets the engine choose
(10, automatically reduced for small smooth-loss fits).
loss_eps: smoothing parameter for the "smooth_*" losses; pick roughly
1% of the typical residual magnitude. Smaller values track the non-smooth
loss more closely but give noisier gradients. Default 0.01.
a numeric vector of weights of the same length as
the number of rows in combinations.
a factor or character matrix to be used in base::by() to
split the data.frame or matrix of set combinations
a character to use to separate the dummy-coded factors if there are factor or character vectors in 'combinations'.
whether to include factor names when constructing dummy codes
euler(default): a named numeric vector, with
combinations separated by an ampersand, for instance A&B = 10.
Missing combinations are treated as being 0.
euler(data.frame): a data.frame of logicals, binary integers, or
factors.
euler(matrix): a matrix that can be converted to a data.frame of logicals
(as in the description above) via base::as.data.frame.matrix().
euler(table): A table with max(dim(x)) < 3.
euler(list): a list of vectors, each vector giving the contents of
that set (with no duplicates). Vectors in the list must be named.
If the input is a matrix or data frame and argument by is specified,
the function returns a list of euler diagrams.
The function minimizes the residual sums of squares,
$$
\sum_{i=1}^n (A_i - \omega_i)^2,
$$
by default, where \(\omega_i\) the size of the ith disjoint subset, and
\(A_i\) the corresponding area in the diagram, that is, the unique
contribution to the total area from this overlap. The loss function
can, however, be controlled via the loss argument.
euler() also returns stress (from venneuler), as well as
diagError, and regionError from eulerAPE.
The stress statistic is computed as
$$ \frac{\sum_{i=1}^n (A_i - \beta\omega_i)^2}{\sum_{i=1}^n A_i^2}, $$ where $$ \beta = \sum_{i=1}^n A_i\omega_i / \sum_{i=1}^n \omega_i^2. $$
regionError is computed as
$$ \left| \frac{A_i}{\sum_{i=1}^n A_i} - \frac{\omega_i}{\sum_{i=1}^n \omega_i}\right|. $$
diagError is simply the maximum of regionError.
Wilkinson L. Exact and Approximate Area-Proportional Circular Venn and Euler Diagrams. IEEE Transactions on Visualization and Computer Graphics (Internet). 2012 Feb (cited 2016 Apr 9);18(2):321-31. Available from: tools:::Rd_expr_doi("10.1109/TVCG.2011.56")
Micallef L, Rodgers P. eulerAPE: Drawing Area-Proportional 3-Venn Diagrams Using Ellipses. PLOS ONE (Internet). 2014 Jul (cited 2016 Dec 10);9(7):e101717. Available from: tools:::Rd_expr_doi("10.1371/journal.pone.0101717")
plot.euler(), print.euler(), eulerr_options(), venn()
# Fit a diagram with circles
combo <- c(A = 2, B = 2, C = 2, "A&B" = 1, "A&C" = 1, "B&C" = 1)
fit1 <- euler(combo)
# Investigate the fit
fit1
# Refit using ellipses instead
fit2 <- euler(combo, shape = "ellipse")
# Investigate the fit again (which is now exact)
fit2
# Plot it
plot(fit2)
# A set with no perfect solution
euler(c(
"a" = 3491, "b" = 3409, "c" = 3503,
"a&b" = 120, "a&c" = 114, "b&c" = 132,
"a&b&c" = 50
))
# Using grouping via the 'by' argument through the data.frame method
euler(fruits, by = list(sex, age))
# Using the matrix method
euler(organisms)
# Using weights
euler(organisms, weights = c(10, 20, 5, 4, 8, 9, 2))
# The table method
euler(pain, factor_names = FALSE)
# A euler diagram from a list of sample spaces (the list method)
euler(plants[c("erigenia", "solanum", "cynodon")])
Run the code above in your browser using DataLab