diff --git a/R/tinyformula.R b/R/tinyformula.R
index 29189061..552e672c 100644
--- a/R/tinyformula.R
+++ b/R/tinyformula.R
@@ -75,7 +75,7 @@ tinyframe = function(formula, data, drop = FALSE) {
## - data: model.frame from full formula
if (is.null(formula)) return(NULL)
vars = attr(terms(formula), "variables")[-1L]
- if (is.null(vars)) return(NULL)
+ if (is.null(vars)) return(data[, 0L, drop = drop])
names = sapply(vars, deparse, width.cutoff = 500L)
data[, names, drop = drop]
}
diff --git a/R/tinyplot.R b/R/tinyplot.R
index 988bfd0e..7f9802bc 100644
--- a/R/tinyplot.R
+++ b/R/tinyplot.R
@@ -1675,45 +1675,73 @@ tinyplot.formula = function(
## extract x (if any)
x = tinyframe(tf$x, mf)
- if (!is.null(x)) {
+ if (!is.null(x) && ncol(x) > 0L) {
xnam = names(x)[[1L]]
if (length(names(x)) > 1L) warning(paste("formula should specify at most one x-variable, using:", xnam),
"\nif you want to use arithmetic operators, make sure to wrap them inside I()")
x = x[[xnam]]
} else {
+ x = NULL
xnam = NULL
}
## extract y (if any)
y = tinyframe(tf$y, mf)
- if (!is.null(y)) {
+ if (!is.null(y) && ncol(y) > 0L) {
ynam = names(y)[[1L]]
if (length(names(y)) > 1L) warning(paste("formula should specify at most one y-variable, using:", ynam),
"\nif you want to use arithmetic operators, make sure to wrap them inside I()")
y = y[[ynam]]
} else {
+ y = NULL
ynam = NULL
}
## extract by (if any)
by = tinyframe(tf$by, mf)
- if (!is.null(by)) {
+ if (!is.null(by) && ncol(by) > 0L) {
bynam = names(by)
by = if (length(bynam) == 1L) by[[bynam]] else interaction(by, sep = ":")
+ } else {
+ by = NULL
}
## extract x/y facet (if formula)
if (!is.null(tf$xfacet) || !is.null(tf$yfacet)) {
+ ## xfacet/yfacet can be either:
+ ## - no formula: NULL
+ ## - formula without variables: empty (zero-column) data
+ ## - formula with variable(s): data frame
xfacet = tinyframe(tf$xfacet, mf)
yfacet = tinyframe(tf$yfacet, mf)
- if (!is.null(xfacet)) xfacet = if (ncol(xfacet) == 1L) xfacet[[1L]] else interaction(xfacet, sep = ":")
- if (!is.null(yfacet)) yfacet = if (ncol(yfacet) == 1L) yfacet[[1L]] else interaction(yfacet, sep = ":")
- if (is.null(yfacet)) {
- facet = xfacet
+ xtype = if (is.null(xfacet)) "none" else if (ncol(xfacet) == 0L) "empty" else "data"
+ ytype = if (is.null(yfacet)) "none" else if (ncol(yfacet) == 0L) "empty" else "data"
+
+ ## turn data frame (if specified) into a single factor
+ if (xtype == "data") xfacet = if (ncol(xfacet) == 1L) xfacet[[1L]] else interaction(xfacet, sep = ":")
+ if (ytype == "data") yfacet = if (ncol(yfacet) == 1L) yfacet[[1L]] else interaction(yfacet, sep = ":")
+
+ ## set up actual facet, potentially with grid information
+ if (xtype %in% c("none", "empty") && ytype %in% c("none", "empty")) {
+ facet = NULL
} else {
- facet = interaction(xfacet, yfacet, sep = "~")
- attr(facet, "facet_grid") = TRUE
- attr(facet, "facet_nrow") = length(unique(yfacet))
+ if (xtype %in% c("none", "empty")) {
+ facet = yfacet
+ if (xtype == "empty") {
+ if (is.null(facet.args)) facet.args = list()
+ if (is.null(facet.args[["nrow"]])) facet.args[["nrow"]] = length(unique(yfacet))
+ }
+ } else if (ytype %in% c("none", "empty")) {
+ facet = xfacet
+ if (ytype == "empty") {
+ if (is.null(facet.args)) facet.args = list()
+ if (is.null(facet.args[["nrow"]])) facet.args[["nrow"]] = 1L
+ }
+ } else {
+ facet = interaction(xfacet, yfacet, sep = "~")
+ attr(facet, "facet_grid") = TRUE
+ attr(facet, "facet_nrow") = length(unique(yfacet))
+ }
}
}
diff --git a/inst/tinytest/_tinysnapshot/facet_density_formula_1col.svg b/inst/tinytest/_tinysnapshot/facet_density_formula_1col.svg
new file mode 100644
index 00000000..c1b4b40e
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/facet_density_formula_1col.svg
@@ -0,0 +1,173 @@
+
+
diff --git a/inst/tinytest/_tinysnapshot/facet_density_formula_1row.svg b/inst/tinytest/_tinysnapshot/facet_density_formula_1row.svg
new file mode 100644
index 00000000..2482307a
--- /dev/null
+++ b/inst/tinytest/_tinysnapshot/facet_density_formula_1row.svg
@@ -0,0 +1,177 @@
+
+
diff --git a/inst/tinytest/test-facet.R b/inst/tinytest/test-facet.R
index 3542c78d..5742d3ac 100644
--- a/inst/tinytest/test-facet.R
+++ b/inst/tinytest/test-facet.R
@@ -475,6 +475,26 @@ f = function() {
}
expect_snapshot_plot(f, label = "facet_density_grid")
+f = function() {
+ tinyplot(
+ ~Ozone, aq,
+ type = "density",
+ facet = 1 ~ hot:windy,
+ main = "Ozone pollution is worse on hot, calm days"
+ )
+}
+expect_snapshot_plot(f, label = "facet_density_formula_1row")
+
+f = function() {
+ tinyplot(
+ ~Ozone, aq,
+ type = "density",
+ facet = hot:windy ~ 1,
+ main = "Ozone pollution is worse on hot, calm days"
+ )
+}
+expect_snapshot_plot(f, label = "facet_density_formula_1col")
+
f = function() {
tinyplot(
~wt,