-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
99 lines (61 loc) · 3.17 KB
/
README
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
92
93
94
95
96
97
For a high-level paradigm, we need to formulate a model specification
paradigm.
Lessons from lattice:
* Formulas and non-standard evaluation has drawbacks, especially for
non-top-level calls, wrappers, etc. However, we do still need to
think about enclosing environments.
* A data-centric approach is good, but the data frame model is too
limited. In other words, the design should anticipate other data
containers (we have a ready-made use-case in flowSets)
* Distinction between primary and conditioning variables is good, but
giving special status to 'x', 'y', etc. has drawbacks. A simple
use-case is densityplot(x=, weights=)
* The ability to specify multiple data sources is useful (something
lattice cannot do well, but ggplot can).
Ideas:
* Specify variables through expression-like objects, with eval-like
functionality, but make the tools explicitly generic to work with
non-standard data sources. Think about attaching an enclosing
environment to these expression-like objects.
* Make the idea of packets concrete. Perhaps a cross-tabulation-like
array, each element an index vector (subscripts, but potentially
more flexible). A "packets" object should have an attached data
object (could be .GlobalEnv). packet[[i]] should have enough
information to extract the corresponding packet from a different
packets object (with the same cross-tabulation)
* Variable evaluation API:
evaluate(expression, data, subset)
evaluate(expression, packet[[i]])
* High-level function calls could be of the form
mosaiq(data = environment(), enclos = .GlobalEnv,
margin.vars = list(a = expression(a), b = expression(b)),
packets = packets(margin.vars, data),
panel.vars = list(x = expression(x), weights = expression(w)), # specific to panel function
panel = qv.panel.densityplot,
prepanel = qv.panel.densityplot,
...)
* One convenient convention is to make each panel function accept an
argument called 'give.limits', so that when called as
panel(..., give.limits = TRUE)
it essentially works as a prepanel function.
* Outline of steps and related functions
- compute.packets : computes packets as a list array
- compute.layout : computes layout -->
will need to match these to packet order;
generates integer-array of dim c(column, row, page), with
packet number as entry (0 for no packet)
- compute.limits : call prepanel function for all packets -->
generates similar list-array, for now of the form list(xlim, ylim)
- combine.limits : combine limits information across packets ->
(1) support types same, free, sliced
(2) allow choice of margins over which to combine
--> results as a list-array again
- create.panels : create list-array of qwidgets, with structure
similar to layout
- create similar list-array of strip.[top|left],
xaxis.[left|right], yaxis.[top|bottom]
- render into page widgets, one for each page in layout[,,page]:
+ draw all panels
+ draw strip.top for row=1:nrow (just 1 for at top)
+ draw strip.left for column=integer(0) (just 1 for left)
+ etc. for axes