I wanted to produce a list of statistics labelled with the statistic name, for exchange with a database.
I defined
defaultStatsHeadings = {"Mean", "Variance", "Skewness", "Kurtosis", "excessKurtosis", "GeometricMean", "Median"};
(where excessKurtosis is user-defined)
and then a function that would apply these as function names to a set of data
ClearAll[statsByHeadings]
(* Most functions are happy, but GeometricMean complains that what is passed is not
non-empty (i.e. its empty because it's on Hold)... but calculates when released -> Just
quieten that message *)
statsByHeadings[data_, headings_:defaultStatsHeadings]:=
Quiet[
Re[
ReleaseHold[
Table[
ToExpression[ToString[statsHeadings[[i]]]<>"["<>ToString[Hold[data]]<>"]"], {i,1,Length[headings]}
]
]
]
,{GeometricMean::vecmat1}
];
(where the Re[] is only really for GeometricMean if the result is complex)
This works, but on application to a large dataset (~1 million values) it is almost two orders of magnitude slower than the direct application of the individual functions.
I think what is happening is that where I wanted to refer to the data by symbol I am actually referring to it by values - and the ToString is converting 1 million values for each call.
So, this was clearly a naive and bad way to achieve my objective.
Question how should/could I achieve the application of functions by name strings as described and how does the right approach work, i.e. I'd like to understand better the use of Hold etc. in this context