corybrunson / ggalluvial

ggplot2 extension for alluvial plots
http://corybrunson.github.io/ggalluvial/
GNU General Public License v3.0
497 stars 34 forks source link

unexpected differing row numbers in stat layers #37

Closed corybrunson closed 5 years ago

corybrunson commented 5 years ago

Description of the issue

An unexpected error is thrown when rendering (not when defining) an alluvial diagram using the stat layers rather than the geom layers with default params. This could be related to #34. This does not seem to affect (at least some of) the more complicated examples installed with the package.

Reproducible example

library(ggalluvial)
#> Loading required package: ggplot2
# toy data set
toy <- data.frame(
  subject = rep(1:3, times = 3),
  collection = rep(1:3, each = 3),
  category = I(c("A", "A", "B", "A", "B", "B", "A", "B", "A"))
)
print(toy)
#>   subject collection category
#> 1       1          1        A
#> 2       2          1        A
#> 3       3          1        B
#> 4       1          2        A
#> 5       2          2        B
#> 6       3          2        B
#> 7       1          3        A
#> 8       2          3        B
#> 9       3          3        A
# stratum stat with default params
ggplot(toy, aes(x = collection, stratum = category)) + stat_stratum()
#> Error in data.frame(structure(list(x = c(1, 1, 2, 2, 3, 3), stratum = c("B", : arguments imply differing number of rows: 6, 0
# stratum geom with default params
ggplot(toy, aes(x = collection, stratum = category)) + geom_stratum()

# flow stat with default params
ggplot(toy, aes(x = collection, stratum = category, alluvium = subject)) +
  stat_flow()
#> Error in data.frame(structure(list(alluvium = c(4, 5, 6, 4, 5, 6, 1, 2, : arguments imply differing number of rows: 12, 0
# flow geom with default params
ggplot(toy, aes(x = collection, stratum = category, alluvium = subject)) +
  geom_flow()

# alluvium stat with default params
ggplot(toy, aes(x = collection, stratum = category, alluvium = subject)) +
  stat_alluvium()
#> Error in data.frame(structure(list(x = c(1, 1, 1, 2, 2, 2, 3, 3, 3), stratum = c("A", : arguments imply differing number of rows: 9, 0
# alluvium geom with default params
ggplot(toy, aes(x = collection, stratum = category, alluvium = subject)) +
  geom_alluvium()

Created on 2019-08-20 by the reprex package (v0.2.1)

corybrunson commented 5 years ago

In the first example, the width parameter, which is necessary to execute GeomStratum$setup_data(), is missing from self$geom_params. Similar problems arise in the other cases. Including the missing parameters "solves" the problems:

library(ggalluvial)
#> Loading required package: ggplot2
# toy data set
toy <- data.frame(
  subject = rep(1:3, times = 3),
  collection = rep(1:3, each = 3),
  category = I(c("A", "A", "B", "A", "B", "B", "A", "B", "A"))
)
print(toy)
#>   subject collection category
#> 1       1          1        A
#> 2       2          1        A
#> 3       3          1        B
#> 4       1          2        A
#> 5       2          2        B
#> 6       3          2        B
#> 7       1          3        A
#> 8       2          3        B
#> 9       3          3        A
# stratum stat with default params
ggplot(toy, aes(x = collection, stratum = category)) + stat_stratum(width = 1/3)

# flow stat with default params
ggplot(toy, aes(x = collection, stratum = category, alluvium = subject)) +
  stat_flow(width = 1/3, knot.pos = 1/6)

# alluvium stat with default params
ggplot(toy, aes(x = collection, stratum = category, alluvium = subject)) +
  stat_alluvium(knot.pos = 1/6)

Created on 2019-08-31 by the reprex package (v0.2.1)

In principle, width and knot.pos are unnecessary for the stats, which might be coupled with the error bar and/or point range geoms, as in the examples. But the error messages above are unhelpful, and (additionally) the code in Geom*$draw_*() does not use default values in place of missing parameters.

corybrunson commented 5 years ago

Note: Consistent with the lack of documentation in the unofficial internals reference, ggplot2 does not seem to admit a $setup_params() method for Geom ggproto objects, though it also does not throw an error when they are defined.