help for multidensity

Kernel density estimation for one or more variables or groups

Syntax

multidensity generate varlist [if] [in]
[weight] [ , generate_options ]
(generate syntax 1)

multidensity generate varname [if] [in]
[weight] [ , generate_options ]
(generate syntax 2)

multidensity super [ , super_options
]

multidensity juxta [ , juxta_options
]

multidensity bystyle [ ,
bystyle_options ]

multidensity clear [ , clear_options ]

fweights and aweights are allowed; see weight.

Description

multidensity is a convenience command for creating and
plotting kernel estimates of probability density for one or (especially)
more variables or for one or (especially) more groups of a specified
variable. It is variously a wrapper for twoway__kdensity_gen and
graph twoway.

In addition to its more obvious use for probability density
estimates for different variables, or for different groups of a single
variable, multidensity is designed to accommodate tasks such as
exploring the effects of different kernel choices or different
bandwidths with the same data. multidensity is also unusual in
supporting estimates of probability density on various transformed
scales, back-transformed to be shown on the original scale.

multidensity hinges on multidensity generate for
generating new variables. Once those are in memory, you can draw
whatever graphs you want or even export the results beyond Stata.
However, multidensity offers three kinds of graphs through
subcommands:

multidensity super superimposes density traces in a
single panel. It is (often) better if you are looking at distributions
with similar magnitudes and identical units of measurement, or even the
same data analysed in different ways.

multidensity juxta draws separate graphs for each
variable and then uses graph combine to produce a combined display
in which graphs are juxtaposed. It is (usually) better if you are
looking at distributions with very different magnitudes and/or units of
measurement.

multidensity bystyle is an alternative in which panels
are presented juxtaposed as if using a by_option for different
groups of a single variable. That is not an illusion, as the dataset is
temporarily reshaped to allow such a plot. The result can
sometimes look better than that from multidensity juxta.

Note that these subcommands, super, juxta and
bystyle, are unusual in not expecting (or even allowing) a
varlist to be specified. They depend on variables left in memory by
a previous multidensity generate.

It is very easy to get into a small mess and especially to
change your mind about what is a good idea, so multidensity clear
is a quick way to clear results out of the way, allowing a fresh start.

Options

Options of multidensity generate

fstub(string) specifies a stub or prefix for names of
variables containing kernel estimates of probability density for each
specified variable. The default is fstub(_density). Thus if 4
variables are specified in varlist, or 4 groups of values specified
by varname , by(byvar), then by default density
estimates will be returned in new or replaced variables
_density1-_density4.

xstub(string) specifies a stub or prefix for names of
variables containing values on a grid approximating the range of each
specified variable, or a greater range. The default is xstub(_x).
Thus if 4 variables or 4 groups are specified, by default grid values
will be returned in new variables _x1-_x4. Such values will be
equally spaced on the scale used for estimation. If estimates are
calculated on a transformed scale, grid values will be equally spaced on
that scale, but returned back-transformed to the original scale.

by(byvar) (allowed with one varname only: see
generate syntax 2 above) specifies the name of a grouping
variable. Density estimates will be produced separately for each
distinct value of byvar. String variables are allowed for
byvar. Missing values of byvar will be ignored unless the
missing option is also specified (see immediately below).

missing (allowed with one varname only: see
generate syntax 2 above) specifies that missing values of
byvar be included in calculations for distinct values specified by
by(byvar).

n(#) specifies the number of values to be included in
each grid for estimation of probability density. The default is
min(_N, 100), where _N is the number of observations in the
entire dataset. If n() is specified to exceed _N, it is
reset to _N with a warning.

minimum(#) specifies that the range of each grid be
extended to a minimum of # if (and only if) # is smaller than
the observed minimum.

maximum(#) specifies that the range of each grid be
extended to a maximum of # if (and only if) # is larger than
the observed maximum.

bwidth(numlist) specifies one or more bandwidths to
override the default chosen by twoway__kdensity_gen. If one
bandwidth is specified, it is applied to all variables or groups of
values specified. If trans() is also specified, the bandwidth must
be on the transformed scale. That may require some experimentation or at
least some prior experience.

kernel(kernel_list) specifies one or more kernels to
override the default chosen by twoway__kdensity_gen, which is
always the Epanechnikov kernel. If one kernel is specified, it is
applied to all variables or groups of values specified.

trans(transformation_list) specifies one or more
transformations to be applied as follows. Data will be transformed as
specified, probability density estimated on that scale, and then
estimates will be back-transformed. For a monotone transformation
T(x) the principle is that for densities f the estimate of
f(x)} is the estimate of f(T(x))
multiplied by |dT/dx| = |T'(x)|.
For discussion and references, see Cox (2004, pp.76-78). On cube
roots, see also Cox (2011). Allowed transformations are

reciprocal or -1, noting that all values must be
positive for this transformation to be applied;

log or ln, meaning natural logarithm, noting that
all values must be positive for this transformation to be applied;

cube_root or 1/3 (type without spaces), noting that
this is implemented for positive, zero and negative values alike;

root or square_root or 1/2 (type without
spaces}, noting that all values must be positive or zero for this
transformation;

logit, noting that all values must be strictly between 0
and 1 for this transformation;

identity or @, noting that this specification is
needed if (and only if) other transformations are used in the same
command.

labelwith(specification) controls the variable labels to
be used for grid variables. By default the variable label of the
original variable is used, or its variable name if no label is attached,
or the value label or value of the distinct group if by() is used.
None of these choices is a good idea if the same data are supplied, but
different kernels, bandwidths or transformations are to be used.
labelwith() allows any or all of kernel, bwidth or
trans to be specified (either in full or as any abbreviation, but
separated by spaces) to indicate use of such elements in variable labels.

densitylabel(string) specifies an alternative variable
label for all generated density variables. The default is "Density".

Options of multidensity super

fstub() and xstub(): see above under
Options of multidensity generate.

recast(newplottype) is flagged as a particularly useful
option. In practice, recast(area) is by far the most useful possibility,
so long as you are using Stata 15 up and can exploit the scope to tune
opacity or transparency.

vertical specifies that axes should be reversed so that
the variable in question is plotted vertically and its density is plotted
horizontally. One reason for doing that is if the variable is naturally
or conventionally regarded as vertical, say that it is an altitude,
elevation, height or depth, as may be encountered in the Earth or
environmental sciences or archaeology.

optall(twoway_options) is a catch-all for options to be
applied to all plotted curves or areas.

opt1(twoway_options) ... opt20(twoway_options)
specify particular options for the 1st density, ..., 20th density
plotted. For example if the 7th density plotted was especially
interesting or important, you might want to assign a special colour or
line thickness using opt7(). The number of 20 such options is
plucked out of the air as more than the number of densities that might
comfortably be distinguished. Any of these options overrides
optall() whenever that is practicable.

addplot(): see addplot_option.

twoway_options are other options of twoway.

Options of multidensity juxta

fstub() and xstub(): see above under
Options of multidensity generate.

recast(): see above under Options of multidensity super.

vertical: see above under Options of multidensity super.

optall() and opt1() to opt20(): see above under
Options of multidensity super.

combineopts() are options of graph combine. For
example, this is where to specify a name or filename for a saved graph.

twoway_options are other options of twoway.

Options of multidensity bystyle

fstub() and xstub(): see above under
Options of multidensity generate.

recast(): see above under Options of multidensity super.

vertical: see above under Options of multidensity super.

byopts() are options of by_option.

twoway_options are other options of twoway.

Options of multidensity clear

fstub() and xstub(): see above under
Options of multidensity generate.

Remarks

multidensity is indicative, not definitive. It encapsulates
some mild prejudices on how its task is best done and does not purport to
address all possible uses of probability density estimates. In
particular, as multidensity tries to make it as easy as possible
to generate a bundle of variables for graphing, so also its attitude is
that such variables may be replaced on each use. The user can
easily protect result variables thought to be interesting or useful by
careful choice of variable names or a save of the dataset.

If two or more of kernel(), bwidth() and
trans() are specified, choices are made in parallel, not
nested. Thus kernel(biweight epan) bwidth(100 20) produces two
plots, not four.

Density estimates are plotted if positive and not plotted if zero.
This is not a bug. You are at liberty to disagree that it is a feature.

The use of transformations here is distinct from the often
sound and sensible idea that a variable should be transformed and
analysed on that scale, period.

Wilke (2019) is articulate on the merits of plotting density
estimates as areas. My review at Amazon.com may be of interest:
https://www.amazon.com/gp/customer-reviews/R22MWD7RJ6QAFP

There are many helpful accounts of density estimation at
various technical levels. The books of Silverman (1986), Scott (1992,
2015) and Simonoff (1996) are especially useful.

Examples

. set scheme s1color

. sysuse auto, clear

. label var price "Price (USD)"

. multidensity gen price, by(foreign) min(0) max(18000)

. multidensity super, name(G1, replace)

. multidensity super, recast(area) opt1(lcolor(orange) color(orange%40)) opt2(lcolor(blue) color(blue%40)) title("Price (USD)") name(G2, replace)

. su _density1, meanonly

. local max = r(max)

. su _density2, meanonly

. local max = max(`max', r(max))

. gen where1 = -`max'/15

. gen where0 = -`max'/30

. local rugcode addplot(scatter where0 price if !foreign, ms(|) mc(orange) || scatter where1 price if foreign, ms(|) mc(blue))

. multidensity super, recast(area) opt1(lcolor(orange) color(orange%40)) opt2(lcolor(blue) color(blue%40)) title("Price (USD)") ytitle(Density) `rugcode' name(G3, replace)

. multidensity clear

. multidensity gen price, kernel(biweight) bw(400 600 800 1000) labelwith(bwidth)

. multidensity super, title(Price (USD)) opt1(lp(dash)) opt3(lp(dash)) xla(4000(4000)16000) name(G4, replace)

. multidensity bystyle, byopts(title(Price (USD)) note("biweight kernels, different bandwidth")) name(G5, replace)

. multidensity clear

. multidensity gen price, trans(identity root cube_root log) labelwith(trans)

. multidensity bystyle, byopts(title(Price (USD)) note("transform, estimate and back-transform")) name(G6, replace)

. multidensity clear

. multidensity gen price weight mpg length

. multidensity juxta, combineopts(name(G7, replace))

. multidensity bystyle, name(G8, replace)

Author

Nicholas J. Cox, Durham University

n.j.cox@durham.ac.uk

References

Cox, N.J. 2004.
Graphing distributions.
Stata Journal 2: 66-88. See esp. pp.76-78.

Cox, N.J. 2011.
Stata tip 96: Cube roots.
Stata Journal 11: 149-154.

Scott, D.W. 1992.
Multivariate Density Estimation: Theory, Practice, and Visualization.
New York: John Wiley.

Scott, D.W. 2015.
Multivariate Density Estimation: Theory, Practice, and Visualization.
Hoboken, NJ: John Wiley.

Silverman, B.W. 1986.
Density Estimation for Statistics and Data Analysis.
London: Chapman and Hall.
[British curiosum: author is Sir Bernard Silverman since 2018]

Simonoff, J.S. 1996.
Smoothing Methods in Statistics.
New York: Springer.

Wilke, C.O. 2019.
Fundamentals of Data Visualization: A Primer on Making Informative and Compelling Figures.
Sebastopol, CA: O'Reilly.

Also see

kdensity, twoway kdensity, twoway__kdensity_gen