0

I'm using latex for my research and I do have a problem. I want to be able to automatically update the values that I mention in the text with values from tables so that when values in the tables change, the values that I mention in the text change as well. I came across this helpful post : Accessing values from tables via "grid search" But yet I'm still struggling to apply it with the following table

\newcommand{\specialcell}[2][c]{\begin{tabularx}[#1]{@{}c@{}}#2\end{tabularx}}
\footnotesize
\newcolumntype{Y}{>{\raggedleft\arraybackslash}X}
\begin{tabularx} {15cm} {@{} l Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y@{}} \\
\toprule
\toprule
\textbf{province}&\textbf{N}&\textbf{Sum}&\textbf{N}&\textbf{Sum} \\
\cmidrule(l{.75em}){2-5} 
&Built dataset& &Scotts database&  \\
\midrule
Alberta&812&3.9&2790&8.5 \\
British Columbia&2966&14.3&3847&11.8 \\
Manitoba&630&3.0&1014&3.1 \\
New Brunswick&408&2.0&713&2.2 \\
Newfound. \& Labr.&63&0.3&288&0.9 \\
New Scotia&458&2.2&774&2.4 \\
North Territories&1&0.0&7&0.0 \\
Nunavut&3&0.0&6&0.0 \\
Ontario&9040&43.5&13788&42.2 \\
Prince Edward Isl.&30&0.1&145&0.4 \\
Quebec&5968&28.7&8452&25.9 \\
Saskatchewan&393&1.9&844&2.6 \\
Yukon&9&0.0&22&0.1 \\
\textbf{Total}&20781&100.0&32690&100.0 \\
\bottomrule
\bottomrule
\addlinespace[.75ex]
\end{tabularx}
\par
\normalsize

Can somebody help me?

LaTeXer
  • 1,492

2 Answers2

1

If the tables have the same structure, you can do as follows:

\documentclass{article}
\usepackage{xparse,siunitx,booktabs}

\newcommand{\specialcell}[2][c]{\begin{tabular}[#1]{@{}c@{}}#2\end{tabular}}

\ExplSyntaxOn

\NewDocumentCommand{\definedata}{mm}
 {% #1 = symbolic name, #2 = data
  % data is in the form province string/province name/N1/Sum1/N2/Sum2
  % comma separated
  \prop_new:c { g_bieda_data_#1_prop }
  \clist_map_inline:nn { #2 }
   {
    \__bieda_data_populate:nn { #1 } { ##1 }
   }
 }

\NewDocumentCommand{\printprovince}{mm}
 {
  \tl_set:Nx \l__bieda_data_row_tl
   {
    \prop_item:cn { g_bieda_data_#1_prop } { #2      } &
    \prop_item:cn { g_bieda_data_#1_prop } { #2-N1   } &
    \prop_item:cn { g_bieda_data_#1_prop } { #2-Sum1 } &
    \prop_item:cn { g_bieda_data_#1_prop } { #2-N2   } &
    \prop_item:cn { g_bieda_data_#1_prop } { #2-Sum2 }
   }
  \tl_use:N \l__bieda_data_row_tl
 }

\NewExpandableDocumentCommand{\retrievedata}{mmm}
 {
  \prop_item:cn { g_bieda_data_#1_prop } { #2-#3 }
 }

\tl_new:N \l__bieda_data_row_tl
\seq_new:N \l__bieda_data_row_seq

\cs_new_protected:Nn \__bieda_data_populate:nn
 {
  \seq_set_split:Nnn \l__bieda_data_row_seq { / } { #2 }
  \prop_gput:cxx { g_bieda_data_#1_prop }
   { \seq_item:Nn \l__bieda_data_row_seq { 1 } }
   { \seq_item:Nn \l__bieda_data_row_seq { 2 } }
  \prop_gput:cxx { g_bieda_data_#1_prop }
   { \seq_item:Nn \l__bieda_data_row_seq { 1 } - N1 }
   { \seq_item:Nn \l__bieda_data_row_seq { 3 } }
  \prop_gput:cxx { g_bieda_data_#1_prop }
   { \seq_item:Nn \l__bieda_data_row_seq { 1 } - Sum1 }
   { \seq_item:Nn \l__bieda_data_row_seq { 4 } }
  \prop_gput:cxx { g_bieda_data_#1_prop }
   { \seq_item:Nn \l__bieda_data_row_seq { 1 } - N2 }
   { \seq_item:Nn \l__bieda_data_row_seq { 5 } }
  \prop_gput:cxx { g_bieda_data_#1_prop }
   { \seq_item:Nn \l__bieda_data_row_seq { 1 } - Sum2 }
   { \seq_item:Nn \l__bieda_data_row_seq { 6 } }
 }
\cs_generate_variant:Nn \prop_gput:Nnn { cxx }

\ExplSyntaxOff

\begin{document}

\begin{table}[htp]

\definedata{first}{
  AB/Alberta/812/3.9/2790/8.5,
  BC/British Columbia/2966/14.3/3847/11.8,
  MB/Manitoba/630/3.0/1014/3.1,
  NB/New Brunswick/408/2.0/713/2.2,
  NL/Newfound. Labr./63/0.3/288/0.9,
  NS/New Scotia/458/2.2/774/2.4,
  NT/Northwest Territories/1/0.0/7/0.0,
  NU/Nunavut/3/0.0/6/0.0,
  ON/Ontario/9040/43.5/13788/42.2,
  PE/Prince Edward Isl./30/0.1/145/0.4,
  QC/Quebec/5968/28.7/8452/25.9,
  SK/Saskatchewan/393/1.9/844/2.6,
  YT/Yukon/9/0.0/22/0.1,
  TOT/\textbf{Total}/20781/100.0/32690/100.0
}

\sisetup{group-minimum-digits=4}

\begin{tabular*}{\textwidth}{
  @{\extracolsep{\fill}}
  l
  S[table-format=5.0]
  S[table-format=3.1]
  S[table-format=5.0]
  S[table-format=3.1]
  @{}
}
\toprule
\textbf{Province} &
\multicolumn{2}{c}{Built dataset} & \multicolumn{2}{c@{}}{Scotts database} \\
\cmidrule(r){2-3}\cmidrule(l){4-5}
&
{\textbf{N}} &
{\textbf{Sum}} &
{\textbf{N}} &
{\textbf{Sum}} \\
\midrule
\printprovince{first}{AB} \\
\printprovince{first}{BC} \\
\printprovince{first}{MB} \\
\printprovince{first}{NB} \\
\printprovince{first}{NL} \\
\printprovince{first}{NS} \\
\printprovince{first}{NT} \\
\printprovince{first}{NU} \\
\printprovince{first}{ON} \\
\printprovince{first}{PE} \\
\printprovince{first}{QC} \\
\printprovince{first}{SK} \\
\printprovince{first}{YT} \\
\printprovince{first}{TOT} \\
\bottomrule
\end{tabular*}

\end{table}

We can retrieve the data: in Alberta, N1 is \retrievedata{first}{AB}{N1}.

\end{document}

The data is packed in a property list and you can have as many of them as you like.

enter image description here

egreg
  • 1,121,712
  • Thank you very much Egreg for your return. Unfortunately, it turns out that my tables don't have the same structure. I was wondering if it could be possible to use the "\savedata, \estauto and \usedata" trick that was in the post so that it could work with any type of table. – Théophile NDJANMOU BIEDA Oct 25 '19 at 15:47
0

One option could perhaps be to use pgfplotstable. This lets you first read in tabular data with \pgfplotstableread, and later typeset that table with \pgfplotstabletypeset. Accessing specific cells can be done with \pgfplotstablegetelem (put in a new macro in the example below).

It might take some getting used to and figuring out how to make the table the way you like it.

\documentclass{article}
\usepackage{pgfplotstable}
\usepackage{booktabs}

\pgfplotstableread[
  col sep=semicolon,
]{
Province;N1;S1;N2;S2
Alberta;812;3.9;2790;8.5
British Columbia;2966;14.3;3847;11.8
Manitoba;630;3.0;1014;3.1
New Brunswick;408;2.0;713;2.2
Newfound. Labr.;63;0.3;288;0.9
New Scotia;458;2.2;774;2.4
Northwest Territories;1;0.0;7;0.0
Nunavut;3;0.0;6;0.0
Ontario;9040;43.5;13788;42.2
Prince Edward Isl.;30;0.1;145;0.4
Quebec;5968;28.7;8452;25.9
Saskatchewan;393;1.9;844;2.6
Yukon;9;0.0;22;0.1
\textbf{Total};20781;100.0;32690;100.0
}\FirstDataset

\pgfplotstableset{
  ints/.style={
    dec sep align,
    column name=#1,
    1000 sep=\,
  },
  ints/.default={},
  1dec/.style={
    dec sep align,
    fixed,
    fixed zerofill,
    precision=1,
    column name=#1
  },
  1dec/.default={}
}

\newcommand\getvaluefromtable[4][]{%
  \pgfplotstablegetelem{#3}{#4}\of#2%
  \pgfmathprintnumber[1000 sep=\,,#1]{\pgfplotsretval}%
}

\begin{document}

\pgfplotstabletypeset[
  every head row/.style={
    before row={
      \toprule
     & \multicolumn{4}{c}{Built dataset} & \multicolumn{4}{c}{Scott's database} \\ \cmidrule(lr){2-5} \cmidrule(lr){6-9}
    },
   after row={\midrule}
  },
  every last row/.style={after row=\bottomrule},
  columns/Province/.style={
    string type,
    column type=l,
    column name=\textbf{Province}
  },
  columns/N1/.style={ints=\textbf{N}},
  columns/S1/.style={1dec=\textbf{Sum}},
  columns/N2/.style={ints=\textbf{N}},
  columns/S2/.style={1dec=\textbf{Sum}}
]{\FirstDataset}

\bigskip

Access values by table name, row number and column name, \textit{e.g.}  \getvaluefromtable{\FirstDataset}{10}{N2}

You can use a numeric index for the column as well: \getvaluefromtable{\FirstDataset}{1}{[index]2}.
Indices are zero-based, hence 14.3 for row 1, column 2.

\end{document}

enter image description here

Torbjørn T.
  • 206,688
  • Thank you Torjorn for your suggestion. But I'm looking for a procedure in which I can call a table with \input for example and be able to collect information from that table. – Théophile NDJANMOU BIEDA Oct 25 '19 at 22:02