Search code examples
vega-litevega

How do I use factorial (!) in a vega formula transform


I am trying to create a histogram of a binomial distribution PMF using a vega js specification.

How is this usually done? The vega expressions does not include functions for choose, or factorial, nor does it include a binomial distribution under the statistical functions.

I also cannot seem to reference other functions within the vega specification (i.e. for yval below).

  "data":[
{"name": "dataset",
"transform": [
  {"type":"sequence", "start": 1, "stop": 50, "step": 1, "as": "seq" },
  {"type": "formula", "as": "xval", "expr": "if(datum.seq<nval,datum.seq,NaN)"},
  {"type": "formula", "as": "yval", "expr": "math.factorial(datum.xval)
  " }
]}],

Thanks.


Solution

  • There is no factorial operation available, but one suitable option might be to approximate it with Stirling's approximation, or perhaps a Stirling series if more accuracy is required.

    For example, in Vega-Lite (view in editor):

    {
      "data": {
        "values": [
          {"n": 0, "factorial": 1},
          {"n": 1, "factorial": 1},
          {"n": 2, "factorial": 2},
          {"n": 3, "factorial": 6},
          {"n": 4, "factorial": 24},
          {"n": 5, "factorial": 120},
          {"n": 6, "factorial": 720},
          {"n": 7, "factorial": 5040},
          {"n": 8, "factorial": 40320},
          {"n": 9, "factorial": 362880},
          {"n": 10, "factorial": 3628800}
        ]
      },
      "transform": [
        {
          "calculate": "datum.n == 0 ? 1 : sqrt(2 * PI * datum.n) * pow(datum.n / E, datum.n)",
          "as": "stirling"
        },
        {"fold": ["factorial", "stirling"]}
      ],
      "mark": "point",
      "encoding": {
        "x": {"field": "n", "type": "quantitative"},
        "y": {"field": "value", "type": "quantitative", "scale": {"type": "log"}},
        "color": {"field": "key", "type": "nominal"}
      }
    }
    

    enter image description here