Skip to content
This repository has been archived by the owner on Feb 9, 2024. It is now read-only.

Options for more streamlined DSL for props() #48

Closed
wch opened this issue Aug 26, 2013 · 7 comments
Closed

Options for more streamlined DSL for props() #48

wch opened this issue Aug 26, 2013 · 7 comments

Comments

@wch
Copy link
Contributor

wch commented Aug 26, 2013

These are some of the possibilities for the DSL for specifying within the props() function. This function has the approximately the same purpose as the aes() function in ggplot2.

A property is either scaled or unscaled. Examples of scaled values are: numeric value mapped to x position, and a categorical variable mapped to colors. Examples of unscaled values are: specifying a constant color for points, like "red", or a column in a data set that contains raw color names, like "#000000", "#ffffff", "red", etc.

The value should also be an expression to be evaluated at render time, a constant value, or a (reactive) input object.

Here are there are six different combinations and some examples of their use:

  1. Scaled expression: Mapping a variable to a property. Similar to aes(x = wt) in ggplot2.
  2. Scaled constant: Used for setting the x or y position of a line/point.
  3. Scaled reactive: For interactive input - perhaps for adding lines at particular x/y values?
  4. Unscaled expression: An expression, which, when evaluated in the data set, returns a vector of raw values, like c("red", "red", "black").
  5. Unscaled constant: A raw value like "red".
  6. Unscaled reactive: Interactive inputs setting color/size/opacity of points.

1 and 5 will probably be the most common use cases.

The options shown below are a subset of a long list of alternatives.

Option 1.5

  • scaled expr: x ~ quote(mpg)
  • scaled cnst: x ~ 1
  • scaled rctv: x ~ input_slider()
  • unscld expr: fill = quote(col)
  • unscld cnst: fill = "red"
  • unscld rctv: fill = input_slider()
  • prop obj : y = prop(...)

Cons: most common operation is longest (~ + quote).

Option 3

  • scaled expr: x ~ mpg
  • scaled cnst: x ~ 1
  • scaled rctv: x ~ input_slider()
  • unscld expr: fill ~ I(col)
  • unscld cnst: fill ~ I("red")
  • unscld rctv: fill ~ I(input_slider())
  • prop obj : y = prop(...)

Cons:

Option 4

  • scaled expr: x ~ mpg
  • scaled cnst: x ~ 1
  • scaled rctv: y = input_slider()
  • unscld expr: fill ~ I(col)
  • unscld cnst: fill = "red", or fill = I("red")
  • unscld rctv: fill = I(input_slider())
  • prop obj : y = prop(...)

Pros: No non-standard evaluation, Hadley can implement easily
Cons: lack of symmetry, confusing

Option 5

By default, expressions are evaluated
~ means to not evaluate the expression

= means to use scale = TRUE
:= means to use scale = FALSE

  • scaled expr: x = ~mpg
  • scaled cnst: x = 1
  • scaled rctv: x = input_slider()
  • unscld expr: fill := ~col
  • unscld cnst: fill := "red"
  • unscld rctv: fill := input_slider()
  • prop obj : y = prop(...)

Option 9

~ means to not evaluate the expression. Also default to scale=TRUE.
= means to evaluate the expression. Also default to scale=FALSE.

scaled() means to force the object to have scale=TRUE
unscaled() means to force the object to have scaled=FALSE

  • scaled expr: x ~ mpg
  • scaled cnst: x = scaled(1)
  • scaled rctv: x = scaled(input_slider())
  • unscld expr: fill ~ unscaled(col)
  • unscld cnst: fill = "red"
  • unscld rctv: fill = input_slider()
  • prop obj : y = prop(...)

Option 10

By default, expressions are evaluated
~ means to not evaluate the expression

Default is to use scale=TRUE
I() means to use scale=FALSE

  • scaled expr: x = ~mpg
  • scaled cnst: x = 1
  • scaled rctv: x = input_slider()
  • unscld expr: fill = ~I(col)
  • unscld cnst: fill = I("red")
  • unscld rctv: fill = I(input_slider())
  • prop obj : y = prop(...)
@hadley
Copy link
Member

hadley commented Aug 27, 2013

Another option from JJ. Like Option 4 + 5: := toggles the standard behaviour:

  • scaled expr: x = ~mpg
  • scaled cnst: x := 1
  • scaled rctv: x := input_slider()
  • unscld expr: fill := ~col
  • unscld cnst: fill = "red"
  • unscld rctv: fill = input_slider()
  • prop obj : y = prop(...)

That way the standard operations (scaled expressions and unscaled constants) just work

@jcheng5
Copy link
Member

jcheng5 commented Aug 27, 2013

Option 1.6

  • scaled expr: x ~ mpg
  • scaled cnst: x ~ I(1)
  • scaled rctv: x ~ input_slider()
  • unscld expr: fill = col
  • unscld cnst: fill = I("red")
  • unscld rctv: fill = input_slider()
  • prop obj : y = prop(...)

I personally really like I() to distinguish between either expr vs. cnst, or scaled vs. unscaled.

@hadley
Copy link
Member

hadley commented Aug 27, 2013

@jcheng5 unfortunately that's really hard to make work because of the x ~ input_slider() - how do you tell if the rhs of the formula should be evaluated or unevaluated?

@jcheng5
Copy link
Member

jcheng5 commented Aug 27, 2013

Oh, so is Option 1.5 equally hard to make work? That's what I was basing it off of.

@jcheng5
Copy link
Member

jcheng5 commented Aug 27, 2013

Oh n/m I get it now.

@jcheng5
Copy link
Member

jcheng5 commented Aug 27, 2013

Is option 3 workable?

@hadley
Copy link
Member

hadley commented Aug 27, 2013

@jcheng5 option 3 has the same problem - I can make it work with some heuristics, but it fail 1% of the time with weird error messages. Option 1.5 is easier to make work because it uses quote as well as ~.

@hadley hadley closed this as completed in 2148d0f Aug 28, 2013
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants