计算数据集的四分位数

计算数据集的四分位数

评论:以下代码取自egreg的答案这里

代码:

\documentclass{beamer}

\usepackage{lmodern}
\usepackage{booktabs}
\usepackage{siunitx}
\usepackage{xparse}

\ExplSyntaxOn

\cs_new_eq:NN \calc \fp_eval:n

\prop_new:N \g_svend_elev_prop
\prop_gput:Nnn \g_svend_elev_prop {A} {6}
\prop_gput:Nnn \g_svend_elev_prop {B} {0}
\prop_gput:Nnn \g_svend_elev_prop {C} {0}
\prop_gput:Nnn \g_svend_elev_prop {D} {3}
\prop_gput:Nnn \g_svend_elev_prop {E} {0}
\prop_gput:Nnn \g_svend_elev_prop {F} {2}
\prop_gput:Nnn \g_svend_elev_prop {G} {1}
\prop_gput:Nnn \g_svend_elev_prop {H} {1}
\prop_gput:Nnn \g_svend_elev_prop {I} {1}
\prop_gput:Nnn \g_svend_elev_prop {J} {5}
\prop_gput:Nnn \g_svend_elev_prop {K} {0}
\prop_gput:Nnn \g_svend_elev_prop {L} {3}
\prop_gput:Nnn \g_svend_elev_prop {M} {7}
\prop_gput:Nnn \g_svend_elev_prop {N} {3}
\prop_gput:Nnn \g_svend_elev_prop {O} {1}
\prop_gput:Nnn \g_svend_elev_prop {P} {1}
\prop_gput:Nnn \g_svend_elev_prop {Q} {0}
\prop_gput:Nnn \g_svend_elev_prop {R} {0}
\prop_gput:Nnn \g_svend_elev_prop {S} {0}
\prop_gput:Nnn \g_svend_elev_prop {T} {2}
\prop_gput:Nnn \g_svend_elev_prop {U} {1}
\prop_gput:Nnn \g_svend_elev_prop {V} {2}
\prop_gput:Nnn \g_svend_elev_prop {W} {0}
\prop_gput:Nnn \g_svend_elev_prop {X} {2}
\prop_gput:Nnn \g_svend_elev_prop {Y} {1}
\prop_gput:Nnn \g_svend_elev_prop {Z} {1}
\prop_gput:Nnn \g_svend_elev_prop {Aa} {4}
\prop_gput:Nnn \g_svend_elev_prop {Ab} {6}
\prop_gput:Nnn \g_svend_elev_prop {Ac} {1}
\prop_gput:Nnn \g_svend_elev_prop {Ad} {1}
\prop_gput:Nnn \g_svend_elev_prop {Ae} {6}
\prop_gput:Nnn \g_svend_elev_prop {Af} {2}
\prop_gput:Nnn \g_svend_elev_prop {Ag} {0}
\prop_gput:Nnn \g_svend_elev_prop {Ah} {3}
\prop_gput:Nnn \g_svend_elev_prop {Ai} {2}
\prop_gput:Nnn \g_svend_elev_prop {Aj} {1}
\prop_gput:Nnn \g_svend_elev_prop {Ak} {0}
\prop_gput:Nnn \g_svend_elev_prop {Al} {0}
\prop_gput:Nnn \g_svend_elev_prop {Am} {0}
\prop_gput:Nnn \g_svend_elev_prop {An} {0}
\prop_gput:Nnn \g_svend_elev_prop {Ao} {0}
\prop_gput:Nnn \g_svend_elev_prop {Ap} {4}

\prop_new:N \g_svend_count_prop
\prop_new:N \g_svend_count_zero_prop
\prop_gput:Nnn \g_svend_count_zero_prop { 0 } { 0 }
\prop_gput:Nnn \g_svend_count_zero_prop { 1 } { 0 }
\prop_gput:Nnn \g_svend_count_zero_prop { 2 } { 0 }
\prop_gput:Nnn \g_svend_count_zero_prop { 3 } { 0 }
\prop_gput:Nnn \g_svend_count_zero_prop { 4 } { 0 }
\prop_gput:Nnn \g_svend_count_zero_prop { 5 } { 0 }
\prop_gput:Nnn \g_svend_count_zero_prop { 6 } { 0 }
\prop_gput:Nnn \g_svend_count_zero_prop { 7 } { 0 }
\prop_gset_eq:NN \g_svend_count_prop \g_svend_count_zero_prop

\tl_new:N \l_svend_number_tl
\tl_new:N \l_svend_count_tl

\DeclareExpandableDocumentCommand{\elev}{m}
 {
  \svend_get_item:n { #1 }
 }

\NewDocumentCommand{\countappearances}{}
 {
  % now \elev will also count
  \cs_set_eq:NN \elev \svend_get_item_count:n
  % reinitialize the counter property list
  \prop_set_eq:NN \g_svend_count_prop \g_svend_count_zero_prop
 }

\DeclareExpandableDocumentCommand{\HowMany}{m}
 {
  \prop_item:Nn \g_svend_count_prop { #1 }
 }

\cs_new:Npn \svend_get_item:n #1
 {
  \prop_item:Nn \g_svend_elev_prop { #1 }
 }

\cs_new_protected:Npn \svend_get_item_count:n #1
 {
  \tl_set:Nx \l_svend_number_tl { \svend_get_item:n { #1 } }
  % print the entry
  \tl_use:N \l_svend_number_tl
  % get the current count
  \tl_set:Nx \l_svend_count_tl
   {
    \prop_item:NV \g_svend_count_prop \l_svend_number_tl
   }
  % advance the count by 1
  \tl_set:Nx \l_svend_count_tl { \int_to_arabic:n { \l_svend_count_tl + 1 } }
  % update the property
  \prop_gput:NVV \g_svend_count_prop \l_svend_number_tl \l_svend_count_tl
 }

\cs_generate_variant:Nn \prop_item:Nn { NV }
\cs_generate_variant:Nn \prop_gput:Nnn { NVV }

\ExplSyntaxOff


\newcommand*\HowManyCumuA{\HowMany{0}}
\newcommand*\HowManyCumuB{\calc{\HowManyCumuA+\HowMany{1}}}
\newcommand*\HowManyCumuC{\calc{\HowManyCumuB+\HowMany{2}}}
\newcommand*\HowManyCumuD{\calc{\HowManyCumuC+\HowMany{3}}}
\newcommand*\HowManyCumuE{\calc{\HowManyCumuD+\HowMany{4}}}
\newcommand*\HowManyCumuF{\calc{\HowManyCumuE+\HowMany{5}}}
\newcommand*\HowManyCumuG{\calc{\HowManyCumuF+\HowMany{6}}}
\newcommand*\HowManyCumuH{\calc{\HowManyCumuG+\HowMany{7}}}
\newcommand*\HowManyTotale{\HowManyCumuH}
\newcommand*\frequency[1]{\calc{round(#1/\HowManyTotale*100,1)}}
\newcommand*\frequencyCumuA{\frequency{\HowMany{0}}}
\newcommand*\frequencyCumuB{\calc{\frequencyCumuA+\frequency{\HowMany{1}}}}
\newcommand*\frequencyCumuC{\calc{\frequencyCumuB+\frequency{\HowMany{2}}}}
\newcommand*\frequencyCumuD{\calc{\frequencyCumuC+\frequency{\HowMany{3}}}}
\newcommand*\frequencyCumuE{\calc{\frequencyCumuD+\frequency{\HowMany{4}}}}
\newcommand*\frequencyCumuF{\calc{\frequencyCumuE+\frequency{\HowMany{5}}}}
\newcommand*\frequencyCumuG{\calc{\frequencyCumuF+\frequency{\HowMany{6}}}}
\newcommand*\frequencyCumuH{\calc{\frequencyCumuG+\frequency{\HowMany{7}}}}


\begin{document}

\begin{frame}

\begin{table}
\centering
\countappearances
\begin{tabular}{*{14}{c}}
\toprule
\elev{A}  & \elev{B}  & \elev{C}  & \elev{D}  & \elev{E}  & \elev{F}  & \elev{G}  &
\elev{H}  & \elev{I}  & \elev{J}  & \elev{K}  & \elev{L}  & \elev{M}  & \elev{N}    \\[0.5ex]
\elev{O}  & \elev{P}  & \elev{Q}  & \elev{R}  & \elev{S}  & \elev{T}  & \elev{U}  &
\elev{V}  & \elev{W}  & \elev{X}  & \elev{Y}  & \elev{Z}  & \elev{Aa} & \elev{Ab}   \\[0.5ex]
\elev{Ac} & \elev{Ad} & \elev{Ae} & \elev{Af} & \elev{Ag} & \elev{Ah} & \elev{Ai} &
\elev{Aj} & \elev{Ak} & \elev{Al} & \elev{Am} & \elev{An} & \elev{Ao} & \elev{Ap}   \\
\bottomrule
\end{tabular}

\bigskip

\begin{tabular}{*{7}{S[table-format = 2.1]} S[table-format = 3]}
\toprule
{$F(0)$} & {$F(1)$} & {$F(2)$} & {$F(3)$} &
{$F(4)$} & {$F(5)$} & {$F(6)$} & {$F(7)$}   \\
\calc{round(\frequencyCumuA,1)} & \calc{round(\frequencyCumuB,1)} &
\calc{round(\frequencyCumuC,1)} & \calc{round(\frequencyCumuD,1)} &
\calc{round(\frequencyCumuE,1)} & \calc{round(\frequencyCumuF,1)} &
\calc{round(\frequencyCumuG,1)} & \calc{round(\frequencyCumuH,1)}   \\
\bottomrule
\end{tabular}
\end{table}

\end{frame}

\end{document}

输出:

输出

问题:如何让 LaTeX 计算数据集的四分位数?我希望有类似宏的东西

\quartileA,,\quartileB\quartileC

并输出相应的

0,,13

(在这种特殊情况下)。

笔记:对于一组有序的数据值,四分位数 A, 和C分别是累积频率达到25%、50%和75%的数据值。

在上面的例子中,F(0) 达到了 25%(因为 F(0) 是达到 25% 后的第一个值;因此,0在这种特殊情况下我想要输出),F(1) 达到了 50%(因为 F(1) 是达到 50% 后的第一个值;因此,1在这种特殊情况下我想要输出),F(3) 达到了 75%(因为 F(3) 是达到 75% 后的第一个值;因此,在这种特殊情况下我想要输出3)。

PS 至少这是我所教级别所使用的定义。

答案1

更新此更新包含可即时发现可能值的代码。这些值必须是数字,但不必是整数。前面提到的与 Beamer 的不兼容性只是因为 Beamer 似乎不可能(如果不是使用技巧的话,也许我没有尝试发现)在框架中使用诸如#1或之类的标记#2;特别是不可能在框架中定义命令。

无论如何,更新都会对 Beamer 进行处理。请参阅答案的下半部分。


第一个答案

在这个答案中,我实现了一个\Percentile宏。然而,数据的可能值(从07)在宏中是硬编码的。

\numexpr方便时我会使用,否则我会使用xintfrac(主要是因为我不想重写四舍五入到定点例程,但在这里一切都可以用来完成\numexpr)。为了方便编码,我使用\xintForxinttools

我简要地提到,这让我发现:

  1. 我无法在 Beamer 框架中使用裸机\xintFor,因为 Beamer 解析器不喜欢看到这个#角色,

1a. 这与 完全无关\xintFor:使用 Beamer 无法在框架内定义命令(将使用#1、 或等...)!!!根据其性质,它与 等标记一起使用,因此无法在 Beamer 框架中使用。当然,宏可以在内部使用它。#2\xintFor#1

  1. 我无法在带有 的列\xintFor的表格中使用。Ssiunitx

我放弃了 Beamer,并使用可扩展宏来替代表格(但即便如此,我发现在使用siunitx时我无法按照我预期的普遍性使用它们)。siunitx

至于代码,它使用内部宏来存储单独的数据,以提高数据检索的效率。

%\documentclass{beamer} 
% Beamer is **incompatible** with non hidden \xintFor in  a frame !!!
% NO (unhidden) \xintFor in a Beamer frame !!

% Also for some reason latex+dvipng raises an error here

% This is dvipng (dvipng (TeX Live)) 1.14 Copyright 2002-2010 Jan-Ake Larsson
% [1 <raw PostScriptdvipng warning: No image output from inclusion of raw PostScript >] 

% must go via pdflatex
\documentclass[varwidth, border=6pt, ignorerest=false]{standalone}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{booktabs}
\usepackage{siunitx}
% siunitx is incompatible with use of \xintFor in a tabular !!
%

% \usepackage{xparse}

\usepackage{xintfrac, xinttools}
% xintfrac mainly for \xintRound because everything else can be emulated with
% \numexpr or \dimexpr in this context
% xinttools for the convenience of \xintFor

\newcommand*\SvendData
                {{{A}{6}}%
                 {{B}{0}}%
                 {{C}{0}}%
                 {{D}{3}}%
                 {{E}{0}}%
                 {{F}{2}}%
                 {{G}{1}}%
                 {{H}{1}}%
                 {{I}{1}}%
                 {{J}{5}}%
                 {{K}{0}}%
                 {{L}{3}}%
                 {{M}{7}}%
                 {{N}{3}}%
                 {{O}{1}}%
                 {{P}{1}}%
                 {{Q}{0}}%
                 {{R}{0}}%
                 {{S}{0}}%
                 {{T}{2}}%
                 {{U}{1}}%
                 {{V}{2}}%
                 {{W}{0}}%
                 {{X}{2}}%
                 {{Y}{1}}%
                 {{Z}{1}}%
                 {{Aa}{4}}%
                 {{Ab}{6}}%
                 {{Ac}{1}}%
                 {{Ad}{1}}%
                 {{Ae}{6}}%
                 {{Af}{2}}%
                 {{Ag}{0}}%
                 {{Ah}{3}}%
                 {{Ai}{2}}%
                 {{Aj}{1}}%
                 {{Ak}{0}}%
                 {{Al}{0}}%
                 {{Am}{0}}%
                 {{An}{0}}%
                 {{Ao}{0}}%
                 {{Ap}{4}}}

% Utility to add Data
% e.g \AddToData \SvendData{WW}{5}
% \newcommand*\AddToData [3]{\odef #1{#1{{#2}{#3}}}}
% But would be better utility to update the private \Svend@Values@..,
% \Svend@Counts@.., \Svend@Cuml@.. macros

\makeatletter

% Possible values 0, 1, 2, 3, 4, 5, 6, 7 hard coded here, we associate to each
% a macro to hold the number of its occurrences

\newcommand*\ResetCounts {%
    \xintFor ##1 in {0, 1, 2, 3, 4, 5, 6, 7}\do {\@namedef{Svend@Counts@##1}{0}}%
}

% \odef does \def with one expansion of replacement text

\newcommand*\ParseData [1]{%
% Defines the private macros underlying \elev and \HowMany
  \xintFor* ##1 in {#1}\do {%
    \expandafter\odef\csname Svend@Values@\@firstoftwo ##1\endcsname {\@secondoftwo ##1}%
    \edef\Svend@tmp {Svend@Counts@\@secondoftwo ##1}%
    \expandafter\odef\csname\Svend@tmp\endcsname 
                   {\the\numexpr\csname\Svend@tmp\endcsname + \@ne}%
  }%
}%

\newcommand*\ComputeCumu {%
% Computes and stores iteratively cumulative counts
% Again the possible values 0, 1, 2, 3, 4, 5, 6, 7 hard coded in this approach
  \xintFor ##1 in {0, 1, 2, 3, 4, 5, 6, 7}\do {%
    \xintifForFirst {\odef\Svend@tmp{\romannumeral-`0\HowMany{0}}}
                    {\odef\Svend@tmp{\the\numexpr\Svend@tmp+\HowMany{##1}}}%
    \expandafter\let\csname Svend@Cumul@##1\endcsname \Svend@tmp
    \xintifForLast {\let\HowManyTotale\Svend@tmp }{}%
  }%
}

% Percentiles: 
% I understand there are various definitions, I used this one : 
%
% P(x) (x=0,1,..,100) is the smallest value V such as the frequency of 
% event {v<= V} is at least x\%. Thus P(100) is the largest V and P(0) is the
% smallest V.

% cf http://en.wikipedia.org/wiki/Percentile 

% first (expandable) method:
% \xintiLt {a}{b}{DO THIS IF a<b}{DO THIS IF a>=b}
% \newcommand*\Percentile [1]{%
%     \xintifLt {\HowManyCumu {0}/\HowManyTotale}{#1/100}{% percentile at least 1
%     \xintifLt {\HowManyCumu {1}/\HowManyTotale}{#1/100}{% percentile at least 2
%     \xintifLt {\HowManyCumu {2}/\HowManyTotale}{#1/100}{% percentile at least 3
%     \xintifLt {\HowManyCumu {3}/\HowManyTotale}{#1/100}{% percentile at least 4
%     \xintifLt {\HowManyCumu {4}/\HowManyTotale}{#1/100}{% percentile at least 5
%     \xintifLt {\HowManyCumu {5}/\HowManyTotale}{#1/100}{% percentile at least 6
%     \xintifLt {\HowManyCumu {6}/\HowManyTotale}{#1/100}{7%
%     }{6}%
%     }{5}%
%     }{4}%
%     }{3}%
%     }{2}%
%     }{1}%
%     }{0}%
% }    

% Possibly faster expandable method, does three comparisons: 
% (based on a binary tree of the possible values)
% The other method above does between 1 and 7 comparisons depending on the input
% Speed gain would show only for larger range of values, for example from 0 to
% 127 rather than from 0 to 7
\newcommand*\Percentile [1]{%
    \xintifLt {\HowManyCumu {3}/\HowManyTotale}{#1/100}
      {% percentile at least 4
      \xintifLt {\HowManyCumu {5}/\HowManyTotale}{#1/100}
        {\xintifLt {\HowManyCumu {6}/\HowManyTotale}{#1/100}{7}{6}}
        {\xintifLt {\HowManyCumu {4}/\HowManyTotale}{#1/100}{5}{4}}%
      }
      {% percentile at most 3
      \xintifLt {\HowManyCumu {1}/\HowManyTotale}{#1/100}
        {\xintifLt {\HowManyCumu {2}/\HowManyTotale}{#1/100}{3}{2}}
        {\xintifLt {\HowManyCumu {0}/\HowManyTotale}{#1/100}{1}{0}}%
        }%
}%



\newcommand*\elev        [1]{\csname Svend@Values@#1\endcsname }
\newcommand*\HowMany     [1]{\csname Svend@Counts@#1\endcsname }
\newcommand*\HowManyCumu [1]{\csname Svend@Cumul@#1\endcsname }

\makeatother

\ResetCounts
\ParseData\SvendData
\ComputeCumu

\begin{document}

\centering
\begin{tabular}{*{14}{c}}
\toprule
\elev{A}  & \elev{B}  & \elev{C}  & \elev{D}  & \elev{E}  & \elev{F}  & \elev{G}  &
\elev{H}  & \elev{I}  & \elev{J}  & \elev{K}  & \elev{L}  & \elev{M}  & \elev{N}    \\[0.5ex]
\elev{O}  & \elev{P}  & \elev{Q}  & \elev{R}  & \elev{S}  & \elev{T}  & \elev{U}  &
\elev{V}  & \elev{W}  & \elev{X}  & \elev{Y}  & \elev{Z}  & \elev{Aa} & \elev{Ab}   \\[0.5ex]
\elev{Ac} & \elev{Ad} & \elev{Ae} & \elev{Af} & \elev{Ag} & \elev{Ah} & \elev{Ai} &
\elev{Aj} & \elev{Ak} & \elev{Al} & \elev{Am} & \elev{An} & \elev{Ao} & \elev{Ap}   \\
\bottomrule
\end{tabular}

\bigskip
% THIS WOULD BE OK:

% \begin{tabular}{*{8}{c}}
% \toprule
% \xintFor #1 in {0, 1, 2, 3, 4, 5, 6}\do {{$F(#1)$}&}{$F(7)$}\\
% \xintFor #1 in {0, 1, 2, 3, 4, 5, 6}\do
%                {\xintRound{1}{\HowManyCumu{#1}/\HowManyTotale [2]}&}100\\
% \bottomrule
% \end{tabular}

% BUT THE SAME WITH 
% \begin{tabular}{*{7}{S[table-format = 2.1]}S[table-format = 3]}
% DOESN'T WORK: ON NE PEUT PAS UTILISER \xintFor DANS UN TABULAR AVEC siunitx !!

%  We can use expandable macros with siunitx

\def\RowA #1{{$F(#1)$}}% EXTRA BRACES NEEDED FOR SIUNITX !!
\def\RowB #1{\xintRound{1}{\HowManyCumu{#1}/\HowManyTotale [2]}}

\begin{tabular}{*{7}{S[table-format = 2.1]}S[table-format = 3]}
\toprule
% PURELY EXPANDABLE MACROS: those work with siunitx ...
% ... BUT don't try to define a macro with parameter here :((
\xintListWithSep {&}{\xintApply\RowA {{0}{1}{2}{3}{4}{5}{6}{7}}}\\
\xintListWithSep {&}{\xintApply\RowB {{0}{1}{2}{3}{4}{5}{6}}}&100\\
\bottomrule
\end{tabular}

\bigskip

\begin{tabular}{*{9}{c}}
\toprule
% strange standalone problem with too long line from
% \xintFor #1 in {0, 10, 25, 33, 50, 66, 75, 90} \do {\textit{Pe}$(#1)$&}\textit{Pe}$(100)$\\
\xintFor #1 in {0, 10, 25, 33, 50, 66, 75, 90} \do {$q(#1)$&}$q(100)$\\
\xintFor #1 in {0, 10, 25, 33, 50, 66, 75, 90} \do {$\Percentile{#1}$&}$7$\\
\bottomrule
\end{tabular}

\end{document}

在此处输入图片描述

我也陷入了麻烦standalone(如代码底部所示),甚至dvipng因为一些我不知道的原因而加入了抱怨的喜剧。


第二个答案

\documentclass[10pt]{beamer}
%\usepackage[paperwidth=25cm]{geometry}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage{booktabs}
\usepackage{siunitx}
\usepackage{xintfrac, xinttools}
% EXTENDED DATA
\newcommand*\SvendData
                {{{A}{6}}%
                 {{B}{0}}%
                 {{C}{0}}%
                 {{D}{3}}%
                 {{E}{0}}%
                 {{F}{2}}%
                 {{G}{1}}%
                 {{H}{1}}%
                 {{I}{1}}%
                 {{J}{5}}%
                 {{K}{0}}%
                 {{L}{3}}%
                 {{M}{7}}%
                 {{N}{3}}%
                 {{O}{1}}%
                 {{P}{1}}%
                 {{Q}{0}}%
                 {{R}{0}}%
                 {{S}{0}}%
                 {{T}{2}}%
                 {{U}{1}}%
                 {{V}{2}}%
                 {{W}{0}}%
                 {{X}{2}}%
                 {{Y}{1}}%
                 {{Z}{1}}%
                 {{Aa}{4}}%
                 {{Ab}{6}}%
                 {{Ac}{1}}%
                 {{Ad}{1}}%
                 {{Ae}{6}}%
                 {{Af}{2}}%
                 {{Ag}{0}}%
                 {{Ah}{3}}%
                 {{Ai}{2}}%
                 {{Aj}{1}}%
                 {{Ak}{0}}%
                 {{Al}{0}}%
                 {{Am}{0}}%
                 {{An}{0}}%
                 {{Ao}{0}}%
                 {{Ap}{4}}%
                 {{NA}{6.5}}%
                 {{NB}{0.5}}%
                 {{NC}{0.5}}%
                 {{ND}{3.5}}%
                 {{NE}{0.5}}%
                 {{NF}{2.5}}%
                 {{NG}{1.5}}%
                 {{NH}{1.5}}%
                 {{NI}{1.5}}%
                 {{NJ}{5.5}}%
                 {{NK}{0.5}}%
                 {{NL}{3.5}}%
                 {{NM}{7.5}}%
                 {{NN}{3.5}}%
                 {{NO}{1.5}}%
                 {{NP}{1.5}}%
                 {{NQ}{0.5}}%
                 {{NR}{0.5}}%
                 {{NS}{0.5}}%
                 {{NT}{2.5}}%
                 {{NU}{1.5}}%
                 {{NV}{2.5}}%
                 {{NW}{0.5}}%
                 {{NX}{2.5}}%
                 {{NY}{1.5}}%
                 {{NZ}{1.5}}%
                 {{NAa}{4.5}}%
                 {{NAb}{6.5}}%
                 {{NAc}{1.5}}%
                 {{NAd}{1.5}}%
                 {{NAe}{6.5}}%
                 {{NAf}{2.5}}%
                 {{NAg}{0.5}}%
                 {{NAh}{3.5}}%
                 {{NAi}{2.5}}%
                 {{NAj}{1.5}}%
                 {{NAk}{0.5}}%
                 {{NAl}{0.5}}%
                 {{NAm}{0.5}}%
                 {{NAn}{0.5}}%
                 {{NAo}{0.5}}%
                 {{NAp}{4.5}}}

\makeatletter

% \odef does \def with one expansion of replacement text

\newcommand*\SvendValues {}
\newcommand*\SvendNumValues {}


\newcommand*\ParseData [1]{%
% Defines the private macros underlying \elev and \HowMany
% This version creates \SvendValues ordered list of values.
%
% For inner efficiency this \SvendValues is with braces, not commas
% (to be used with \xintFor* not \xintFor)
%
% The values do not have to be integers. But they must be numeric quantities
% as understood by xintfrac.
%
  \def\SvendValues {}%
  \def\SvendNumValues {0}%
  \xintFor* ##1 in {#1}\do 
  {%
% get the possibly new value
    \odef\Svend@tmpD {\@firstoftwo ##1}%
    \odef\Svend@tmpV {\@secondoftwo ##1}%
% and insert it at the correct location in \SvendValues
% (the better would be to manage some kind of heap tree but I have not
% invested the needed time)
%
    \def\SvendValues@Tmp {}%
    \def\Svend@tmpflag  {0}%
% 0 = initial state, 
% 1 = inserted, finish, 
% 2 = was already there
    \xintifForFirst 
    {\odef\SvendValues {\expandafter{\Svend@tmpV}}%
     \def\SvendNumValues{1}%
     \expandafter\odef\csname Svend@Counts@\Svend@tmpV\endcsname {0}}% will be increased below
    {\xintFor* ##2 in {\SvendValues}\do 
      {%
      \if0\Svend@tmpflag\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
         {\xintifCmp {\Svend@tmpV}{##2}
          {\def\Svend@tmpflag{1}%
           \oodef\SvendValues@Tmp
                 {\expandafter\SvendValues@Tmp \expandafter{\Svend@tmpV}{##2}}}% new < old
          {\def\Svend@tmpflag{2}\odef\SvendValues@Tmp {\SvendValues@Tmp {##2}}}% old = new
          {\odef\SvendValues@Tmp {\SvendValues@Tmp {##2}}}% new > old
         }
         {\odef\SvendValues@Tmp{\SvendValues@Tmp {##2}}}%
      }%
     \if0\Svend@tmpflag
         \oodef\SvendValues@Tmp{\expandafter\SvendValues@Tmp\expandafter {\Svend@tmpV}}%
     \fi
     \let\SvendValues\SvendValues@Tmp
%\typeout{\SvendValues}% debugging
     \if2\Svend@tmpflag
      \else
      % new value
      \expandafter\odef\csname Svend@Counts@\Svend@tmpV\endcsname {0}% will be increased below
      \odef\SvendNumValues {\the\numexpr\SvendNumValues+\@ne}\fi
    }%
% continued as in earlier code
    \expandafter\odef\csname Svend@Values@\Svend@tmpD\endcsname {\Svend@tmpV}%
    \expandafter\odef\csname Svend@Counts@\Svend@tmpV\endcsname 
                   {\the\numexpr\csname Svend@Counts@\Svend@tmpV\endcsname + \@ne}%
  }% end of external \xintFor loop
}%

\newcommand*\ComputeCumu {%
% Computes and stores iteratively cumulative counts
% THIS VERSION USES \SvendValues
  \xintFor* ##1 in {\SvendValues}\do {%
    \xintifForFirst {\odef\Svend@tmp{\romannumeral-`0\HowMany{##1}}}
                    {\odef\Svend@tmp{\the\numexpr\Svend@tmp+\HowMany{##1}}}%
    \expandafter\let\csname Svend@Cumul@##1\endcsname \Svend@tmp
    \xintifForLast {\let\HowManyTotale\Svend@tmp }{}%
  }%
}

% Percentiles: 
%
% P(x) (x=0,1,..,100) is the smallest value V such as the frequency of 
% event {v<= V} is at least x\%. Thus P(100) is the largest V and P(0) is the
% smallest V.

% 
% THIS VERSION USES \SvendValues
% It has nothing hardcoded.

\catcode`_ 11
\def\Percentile@helper #1#2% space below is to stop premature expansion
    { \if1\xintifLt {\HowManyCumu {#2}/\HowManyTotale}{#1/100}{0}{1}\xint_dothis{#2}\fi}

\newcommand*\Percentile [1]{% expandable !
    \xintApplyUnbraced{\Percentile@helper {#1}}\SvendValues\xint_orthat {}%
}

\catcode`_ 8

\newcommand*\elev        [1]{\csname Svend@Values@#1\endcsname }
\newcommand*\HowMany     [1]{\csname Svend@Counts@#1\endcsname }
\newcommand*\HowManyCumu [1]{\csname Svend@Cumul@#1\endcsname }

\let\firstoftwo\@firstoftwo
\let\secondoftwo\@secondoftwo
\makeatother


\ParseData\SvendData
\ComputeCumu
%\typeout{\meaning\SvendValues}

% for first tabular
% WITH BEAMER I CAN NOT DEFINE THIS IN THE FRAME !!!!!!

% ANY \newcommand MUST BE IN THE PREAMBLE WITH BEAMER !!!!!!

\newcommand*\Row [1]{\stepcounter{rowcount}%
                     \elev{\firstoftwo #1}%
                     \ifnum\value{rowcount}<14
                     \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
                     {&}{\setcounter{rowcount}{0}\\[0.5ex]}}

% for middle data (not a tabular, would be too wide)
\newcommand*\ShowCumu [1]{$F(#1)=\xintRound{1}{\HowManyCumu{#1}/\HowManyTotale [2]}$}

% for third tabular

\newcommand*\RowA [1]{$q(#1)$}%
\newcommand*\RowB [1]{$\Percentile{#1}$}



\newcounter{rowcount}


\begin{document}\small

% DEBUGGING (not possible with  Beamer! because of #1...)
% \HowMany{0}

% \xintFor*#1 in \SvendValues\do {[#1,\HowMany{#1}], }
% \SvendNumValues

% \xintNthElt{0}{\SvendData}

% \HowManyTotale

\begin{frame}
\centering
\setcounter{rowcount}{0}%

\begin{tabular}{*{14}{c}}
\toprule
\xintApplyUnbraced \Row\SvendData
\bottomrule
\end{tabular}

\bigskip

% (This is too wide hence would make letters in my png appear too small)

% DEFINITIONS LIKE THIS MUST BE MOVED TO PREAMBLE IF BEAMER CLASS !!
% \def\RowA #1{{$F(#1)$}}% EXTRA BRACES NEEDED FOR SIUNITX !!
% \def\RowB #1{\xintRound{1}{\HowManyCumu{#1}/\HowManyTotale [2]}}

% \centerline{\begin{tabular}{*{\SvendNumValues}{S[table-format = 2.1]}}
% \toprule
% \xintListWithSep {&}{\xintApply\RowA \SvendValues}\\
% \xintListWithSep {&}{\xintApply\RowB \SvendValues}\\
% \bottomrule
% \end{tabular}}

\xintListWithSep{,\quad }{\xintApply\ShowCumu \SvendValues}

\bigskip

\begin{tabular}{*{10}{c}}
\toprule
\xintListWithSep {&}{\xintApply\RowA {{0}{10}{25}{33}{50}{66}{75}{90}{100}}}\\
\xintListWithSep {&}{\xintApply\RowB {{0}{10}{25}{33}{50}{66}{75}{90}{100}}}\\
\bottomrule
\end{tabular}

\end{frame}

\end{document}

在此处输入图片描述

相关内容