4
$\begingroup$

There is a set of one-dimensional descriptive statistics that I need so often that instead of copying and pasting calculations each time I created a function (generateStatsX[...]) that returns all values in a single list into a second function (statisticalAnalysis[...]). But now I am left having to reassign a name (a variable) to each value so I could use them in further calculations. The code below works but I feel it could be done more expediently within function statisticalAnalysis[...]. Is there better way to code this? Please note that I am looking for a solution that does not pollute the Global space.

generateStatsX[raw_, bias_ : Infinity, declen_ : 2] := 
 Block[{len, n, range, midrange, μ, median, mode, σavg, 
   rms, σ2, σ, Em, Es, skew, kurt, mean},
  {len = Length[raw],(* true length of raw data *)
   n = If[len <= bias, len - 1, len, len - 1],(* 
   adjusted length removes bias in variance if n ≤ 
   bias cutoff *)
   range = Max[raw] - Min[raw],
   midrange = Min[raw] + range/2,
   μ = Mean[raw],
   median = Median[raw],
   mode = Commonest[raw][[1]],
   σavg = Sum[Abs[raw[[x]] - μ], {x, 1, len}]/len,
   rms = Sqrt[Sum[(raw[[x]] - μ)^2, {x, 1, len}]/len],
   σ2 = Total[(raw - μ)^2]/n, (* variance *)
   σ = Sqrt[σ2],(* standard deviation *)
   Es = .6745 σ,(* 
   error for single x with 50% of data within 1 std deviation *)
   Em = Es/Sqrt[n],(* standard error of the mean *)
   skew = Skewness[raw],
   kurt = Kurtosis[raw],
   mean = 
    ToString[NumberForm [μ, {Infinity, declen}]] <> 
     " ± " <> ToString[NumberForm[Em, {Infinity, declen}]]}
  ]
statisticalAnalysis[raw_] := Block[{stats, vars},
  stats = generateStatsX[raw];
  vars = {len = stats[[1]], n = stats[[2]], range = stats[[3]], 
    midrange = stats[[4]], μ = stats[[5]], median = stats[[6]], 
    mode = stats[[7]], σavg = stats[[8]], 
    rms = stats[[9]], σ2 = stats[[10]], σ = stats[[11]],
     Em = stats[[12]], Es = stats[[13]], skew = stats[[14]], 
    kurt = stats[[15]], mean = stats[[16]]};
  Row[{len, n, range}, "  |  "] (* 
  demo first 3 variables as proof of concept *)
  ]
statisticalAnalysis[{1.32, 1.37, 1.43, 1.32, 1.36, 1.33, 1.38, 1.35, 
  1.48, 1.28, 1.31, 1.52, 1.51, 1.33, 1.32, 1.27, 1.35, 1.40, 1.27, 
  1.39, 1.50, 1.31, 1.34, 1.48, 1.36, 1.33, 1.40, 1.29, 1.35, 1.36, 
  1.33, 1.30, 1.28, 1.32, 1.34, 1.33, 1.29, 1.34, 1.34, 1.29, 1.35, 
  1.52, 1.29, 1.38, 1.40, 1.28, 1.36, 1.36, 1.32, 1.62, 1.36, 1.34, 
  1.33, 1.33, 1.30, 1.31, 1.33, 1.32, 1.36, 1.41}]
$\endgroup$

1 Answer 1

5
$\begingroup$

If I understand you right, you have names of variables, and have list of values and want to assign variables to values?

In this case, one way could be

Clear["Global`*"];
values = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
vars = {len, n, range, midrange, μ, median, mode, σavg, 
                 rms, σ2, σ, Em, Es, skew, kurt, mean};

Then do

 MapThread[Set, {vars, values}]

Now they are assigned.

$\endgroup$
3
  • $\begingroup$ thank you so much. you came through for ne again. it works beautifully and such an elegant solution. $\endgroup$ Commented May 19, 2020 at 22:40
  • 1
    $\begingroup$ Also Evaluate[vars] = values. $\endgroup$
    – corey979
    Commented May 19, 2020 at 22:45
  • 1
    $\begingroup$ I really wish there was something like ScanThread[]... $\endgroup$ Commented May 20, 2020 at 1:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.