Der Befehl "discard if equal={1.0}" von @Henri

Open in Online-Editor
% 1en ausblenden ====================
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \ifdim##1pt=#1pt
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      \fi
    }
  },
}
% ==============================

wird in folgender Tabelle manchmal nicht ausgeführt.

Woran kann das liegen? Und wie korrigiert man das?

alt text

Open in Online-Editor
%\documentclass[varwidth, border=10pt]{standalone}
\documentclass[paper=a5]{scrbook}
\usepackage[left=1cm, right=1cm]{geometry}

\usepackage{selinput}
\SelectInputMappings{adieresis={ä},  germandbls={ß}}
\usepackage[ngerman]{babel}

\usepackage{pgfplotstable}
\usepackage{amsmath, amssymb, amsfonts}% \binom
\usepackage{colortbl}% \rowcolor, \cellcolor
%\usepackage{multirow}
\usepackage{hhline}
\usepackage{diagbox}  % \diagbox
\usepackage{xcolor, booktabs}

\usepackage{filecontents}

\begin{document}
\setlength\arrayrulewidth{0.905pt} % Um rules deutlich anzuzeigen

\begin{filecontents}{n5.txt}
5  0  0.5905  0.3277  0.2373  0.1681  0.0778  0.0313
5  1  0.9185  0.7373  0.6328  0.5282  0.3370  0.1875
5  2  0.9914  0.9421  0.8965  0.8369  0.6826  0.5000
5  3  0.9995  0.9933  0.9844  0.9692  0.9130  0.8125
5  4  1.0000  0.9997  0.9990  0.9976  0.9898  0.9688
10 0 0.34868    0.10737 0.05631 0.02825 0.00605 0.00098
10 1 0.73610    0.37581 0.24403 0.14931 0.04636 0.01074
10 2 0.92981    0.67780 0.52559 0.38278 0.16729 0.05469
10 3 0.98720    0.87913 0.77588 0.64961 0.38228 0.17188
10 4 0.99837    0.96721 0.92187 0.84973 0.63310 0.37695
10 5 0.99985    0.99363 0.98027 0.95265 0.83376 0.62305
10 6 0.99999    0.99914 0.99649 0.98941 0.94524 0.82813
10 7 1.00000    0.99992 0.99958 0.99841 0.98771 0.94531
10 8 1.00000    1.00000 0.99997 0.99986 0.99832 0.98926
10 9 1.00000    1.00000 1.00000 0.99999 0.99990 0.99902
\end{filecontents}

% ===============================
% ===============================
% Tabelle Summierte Binomial-Verteilung (SumBinVert)
% ===============================
% ===============================

% Farben in Tabelle =====================
\colorlet{FarbeOben}{pink}
\colorlet{FarbeUnten}{lightgray!60}
% ===============================

% Allgemeine Formatierungen für Tabelle (Schrift etc.) festlegen
\pgfplotstableset{
  foreach column append style/.code 2 args = {
    \pgfplotsforeachungrouped \col in {#1} {
      \pgfplotstableset{
        /pgfplots/table/columns/\col/.append style = {#2}
      }
    }
  }
}
% ===============================

% Erste Zeile =========================
\def\SumBinVertHinweisEinsen{%
{\text{\tiny Nicht aufgeführte Werte sind (gerundet auf $4$ Dezimalstellen) gleich $1.0000$}}
}%
% --------------------------
\def\SumBinVertFormel{%
$\begin{matrix}
\displaystyle P(X\leq k) 
= 
\sum_{v=0}^k \binom{n}{v} p^v (1-p)^{n-v} \\
\SumBinVertHinweisEinsen
\end{matrix}$
}%
% --------------------------
\newcommand\ErsteZeile{%
\hhline{~|-------|}  &
\multicolumn{7}{c|}{\cellcolor{FarbeOben} \SumBinVertFormel} \\ 
\hhline{~|-------|}
\rowcolor{FarbeOben}
}%
% ==============================

% Letzte Zeile ========================
\def\SumBinVertHinweisGrauzeile{%
{\tiny$
\begin{array}{l}
\text{Bei grau unterlegtem Eingang, d.h. $p \geq 0{,}5$: } %\\
\text{$P(X\leq k) = 1 -\langle\texttt{Ablesewert}\rangle$}
\end{array}
$}
}%
% --------------------------
\newcommand\LetzteZeile{%
\hhline{~|-------|-|}
\rowcolor{FarbeUnten} 
\multicolumn{1}{c}{\cellcolor{white}} &  
\cellcolor{white} &  
$0{,}9$ & 
$0{,}8$ & 
$0{,}75$ & 
$0{,}7$ & 
$0{,}6$ &  
$0{,}5$ & 
\diagbox{$p$}{$k$}  \\ 
% Anderes Design
\hhline{~~|>{\arrayrulecolor{FarbeUnten}}------>{\arrayrulecolor{black}}|-|}
%
   \rowcolor{FarbeUnten} 
\multicolumn{1}{c}{\cellcolor{white}} &
\multicolumn{1}{c|}{\cellcolor{white}} & 
\multicolumn{7}{l|}{\SumBinVertHinweisGrauzeile} %& \cellcolor{FarbeUnten}  
\\  
\hhline{~~|-------|}
}%
% ==============================

% 1en ausblenden ====================
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \ifdim##1pt=#1pt
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      \fi
    }
  },
}
% ==============================

% Tabellen einlesen
\pgfplotstableread{n5.txt}{\SumBinVertTab}  
%\pgfplotstableread{n10.txt}{\nX}   % "n Römische Zahl"

% Tabellen zusammenführen % ToDO
%%\pgfplotstableread{dataA.dat}\dataA
%%\pgfplotstableread{dataB.dat}\dataB
%
%\pgfplotstablecreatecol[copy column from table={\nX}{[index] 0}] {par1} {\SumBinVertTab}
%\pgfplotstablecreatecol[copy column from table={\nX}{[index] 1}] {par2} {\SumBinVertTab}
%
%\pgfplotstabletypeset{\SumBinVertTab} \\
% --------------------------
% Tabelle setzen
\pgfplotstabletypeset[
% Allgemeine Einstellungen
fixed zerofill, 
fixed, 
precision=4,
% Null-Kommas Beseitigen
%ignore chars={\.0}, 
% --------------------------
% Erste Zeile definieren
every head row/.style = {
before row={\ErsteZeile},  
after row=\hline
},
% --------------------------
% Letzte Zeile definieren
every last row/.style = { 
after row={\LetzteZeile}, 
}, 
% --------------------------
% Nullte nSpalte definieren
create on use/nSpalte/.style = {%%
precision=0,
column type={|c},
create col/assign/.code = {%
  \edef\nMethode{\ifnum \thisrow{1} = 0 \thisrow{0} \fi}
   \pgfkeyslet{/pgfplots/table/create col/next content}\nMethode
},%
},%%
columns/nSpalte/.style = {%
column name ={\cellcolor{white}$n$},
precision=0,
column type={c},
},%
% --------------------------
% Erste k-Spalte definieren
columns/1/.style = {
  column name={\diagbox{$k$}{$p$}},
  precision=0,
  column type={|>{\cellcolor{FarbeOben}\scriptsize}c|},
},
% --------------------------
% Letzte kSymSpalte definieren
create on use/kSymSpalte/.style={%
  create col/expr={\thisrow{0}-1-\thisrow{1}},
},%
columns/kSymSpalte/.style={%
  column name={\multicolumn1c{\cellcolor{white}}}, %$n-1-k$
  column type={|>{\cellcolor{FarbeUnten}\scriptsize}c|},
  precision=0
},%
% --------------------------
% Übrige Spalten benenen
columns/2/.style = {column name={$0{,}1$},discard if equal={1.0}},
columns/3/.style = {column name={$0{,}2$},discard if equal={1.0}},
columns/4/.style = {column name={$0{,}25$},discard if equal={1.0}},
columns/5/.style = {column name={$0{,}3$},discard if equal={1.0}},
columns/6/.style = {column name={$0{,}4$},discard if equal={1.0}},
columns/7/.style = {column name={$0{,}5$},discard if equal={1.0}},
% --------------------------
% Einsen beseitigen
%discard if equal={1.0}, % ToDo: Wie nur auf columns 1-6 anwenden?
% --------------------------
% "Null Komma" in Tabelle beseitigen
% ToDo....
% --------------------------
% Allgemeine Formatierungen festlegen
 foreach column append style={nSpalte,2,3,4,5,6,7}{column type/.add={>{\scriptsize}}{}},
% Angezeigte Spalten definieren
columns={nSpalte,1,2,3,4,5,6,7,kSymSpalte} 
]{\SumBinVertTab}

\bigskip

%\def\getcell#1#2{
%\pgfplotstablegetelem{#1}{#2}\of{\SumBinVertTab}\pgfplotsretval%
%}
%
%$P(X \leq k) = B(n,p;k) = \getcell{0}{2}$
%
%$P(X = k) = P(X \leq k) - P(X \leq k-1) = B(n,p;k) - B(n,p;k-1)  = ???$
\end{document}

gefragt 20 Jan, 10:40

cis's gravatar image

cis
5.4k860167
Akzeptiert: 68%

1

\ifdim tut wunderbar. Allerdings werden Zahlen wie 0.99999 erst nach dem Vergleich auf vier Nachkommastellen gerundet, was dann 1.0000 ergibt.

(20 Jan, 11:04) Henri

Mit

Open in Online-Editor
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \typeout{##1=#1?}%
      \ifdim##1pt=#1pt
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      \fi
    }
  },
}

findet man schnell heraus, dass beispielsweise 0.99999 mit 1.0. verglichen wird. Das ist dann in der Tat nicht gleich. Wird später allerdings auf vier Nachkommastellen gerundet, dann sind die Zahlen gleich. Also müsste man entweder bereits an dieser Stelle runden oder den Vergleich mit etwas Unschärfe versehen:

Open in Online-Editor
\documentclass[paper=a5]{scrbook}
\usepackage[left=1cm, right=1cm]{geometry}

\usepackage{selinput}
\SelectInputMappings{adieresis={ä},  germandbls={ß}}
\usepackage[ngerman]{babel}

\usepackage{pgfplotstable}
\usepackage{amsmath, amssymb, amsfonts}% \binom
\usepackage{colortbl}% \rowcolor, \cellcolor
%\usepackage{multirow}
\usepackage{hhline}
\usepackage{diagbox}  % \diagbox
\usepackage{xcolor, booktabs}

\usepackage{filecontents}

\begin{document}
\setlength\arrayrulewidth{0.905pt} % Um rules deutlich anzuzeigen

\begin{filecontents}{n5.txt}
5  0  0.5905  0.3277  0.2373  0.1681  0.0778  0.0313
5  1  0.9185  0.7373  0.6328  0.5282  0.3370  0.1875
5  2  0.9914  0.9421  0.8965  0.8369  0.6826  0.5000
5  3  0.9995  0.9933  0.9844  0.9692  0.9130  0.8125
5  4  1.0000  0.9997  0.9990  0.9976  0.9898  0.9688
10 0 0.34868    0.10737 0.05631 0.02825 0.00605 0.00098
10 1 0.73610    0.37581 0.24403 0.14931 0.04636 0.01074
10 2 0.92981    0.67780 0.52559 0.38278 0.16729 0.05469
10 3 0.98720    0.87913 0.77588 0.64961 0.38228 0.17188
10 4 0.99837    0.96721 0.92187 0.84973 0.63310 0.37695
10 5 0.99985    0.99363 0.98027 0.95265 0.83376 0.62305
10 6 0.99999    0.99914 0.99649 0.98941 0.94524 0.82813
10 7 1.00000    0.99992 0.99958 0.99841 0.98771 0.94531
10 8 1.00000    1.00000 0.99997 0.99986 0.99832 0.98926
10 9 1.00000    1.00000 1.00000 0.99999 0.99990 0.99902
\end{filecontents}

% ===============================
% ===============================
% Tabelle Summierte Binomial-Verteilung (SumBinVert)
% ===============================
% ===============================

% Farben in Tabelle =====================
\colorlet{FarbeOben}{pink}
\colorlet{FarbeUnten}{lightgray!60}
% ===============================

% Allgemeine Formatierungen für Tabelle (Schrift etc.) festlegen
\pgfplotstableset{
  foreach column append style/.code 2 args = {
    \pgfplotsforeachungrouped \col in {#1} {
      \pgfplotstableset{
        /pgfplots/table/columns/\col/.append style = {#2}
      }
    }
  }
}
% ===============================

% Erste Zeile =========================
\def\SumBinVertHinweisEinsen{%
{\text{\tiny Nicht aufgeführte Werte sind (gerundet auf $4$ Dezimalstellen) gleich $1.0000$}}
}%
% --------------------------
\def\SumBinVertFormel{%
$\begin{matrix}
\displaystyle P(X\leq k) 
= 
\sum_{v=0}^k \binom{n}{v} p^v (1-p)^{n-v} \\
\SumBinVertHinweisEinsen
\end{matrix}$
}%
% --------------------------
\newcommand\ErsteZeile{%
\hhline{~|-------|}  &
\multicolumn{7}{c|}{\cellcolor{FarbeOben} \SumBinVertFormel} \\ 
\hhline{~|-------|}
\rowcolor{FarbeOben}
}%
% ==============================

% Letzte Zeile ========================
\def\SumBinVertHinweisGrauzeile{%
{\tiny$
\begin{array}{l}
\text{Bei grau unterlegtem Eingang, d.h. $p \geq 0{,}5$: } %\\
\text{$P(X\leq k) = 1 -\langle\texttt{Ablesewert}\rangle$}
\end{array}
$}
}%
% --------------------------
\newcommand\LetzteZeile{%
\hhline{~|-------|-|}
\rowcolor{FarbeUnten} 
\multicolumn{1}{c}{\cellcolor{white}} &  
\cellcolor{white} &  
$0{,}9$ & 
$0{,}8$ & 
$0{,}75$ & 
$0{,}7$ & 
$0{,}6$ &  
$0{,}5$ & 
\diagbox{$p$}{$k$}  \\ 
% Anderes Design
\hhline{~~|>{\arrayrulecolor{FarbeUnten}}------>{\arrayrulecolor{black}}|-|}
%
   \rowcolor{FarbeUnten} 
\multicolumn{1}{c}{\cellcolor{white}} &
\multicolumn{1}{c|}{\cellcolor{white}} & 
\multicolumn{7}{l|}{\SumBinVertHinweisGrauzeile} %& \cellcolor{FarbeUnten}  
\\  
\hhline{~~|-------|}
}%
% ==============================

% 1en ausblenden ====================
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \typeout{##1=#1?}% Zu Debugging-Zwecken
      \ifdim \dimexpr ##1pt-#1pt>-0.00005pt
        \ifdim \dimexpr ##1pt-#1pt<0.00005pt
          \typeout{Ja}% Zur Kontrolle
          \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
        \fi
      \fi
    }
  },
}
% ==============================

% Tabellen einlesen
\pgfplotstableread{n5.txt}{\SumBinVertTab}  
%\pgfplotstableread{n10.txt}{\nX}   % "n Römische Zahl"

% Tabellen zusammenführen % ToDO
%%\pgfplotstableread{dataA.dat}\dataA
%%\pgfplotstableread{dataB.dat}\dataB
%
%\pgfplotstablecreatecol[copy column from table={\nX}{[index] 0}] {par1} {\SumBinVertTab}
%\pgfplotstablecreatecol[copy column from table={\nX}{[index] 1}] {par2} {\SumBinVertTab}
%
%\pgfplotstabletypeset{\SumBinVertTab} \\
% --------------------------
% Tabelle setzen
\pgfplotstabletypeset[
% Allgemeine Einstellungen
fixed zerofill, 
fixed, 
precision=4,
% Null-Kommas Beseitigen
%ignore chars={\.0}, 
% --------------------------
% Erste Zeile definieren
every head row/.style = {
before row={\ErsteZeile},  
after row=\hline
},
% --------------------------
% Letzte Zeile definieren
every last row/.style = { 
after row={\LetzteZeile}, 
}, 
% --------------------------
% Nullte nSpalte definieren
create on use/nSpalte/.style = {%%
precision=0,
column type={|c},
create col/assign/.code = {%
  \edef\nMethode{\ifnum \thisrow{1} = 0 \thisrow{0} \fi}
   \pgfkeyslet{/pgfplots/table/create col/next content}\nMethode
},%
},%%
columns/nSpalte/.style = {%
column name ={\cellcolor{white}$n$},
precision=0,
column type={c},
},%
% --------------------------
% Erste k-Spalte definieren
columns/1/.style = {
  column name={\diagbox{$k$}{$p$}},
  precision=0,
  column type={|>{\cellcolor{FarbeOben}\scriptsize}c|},
},
% --------------------------
% Letzte kSymSpalte definieren
create on use/kSymSpalte/.style={%
  create col/expr={\thisrow{0}-1-\thisrow{1}},
},%
columns/kSymSpalte/.style={%
  column name={\multicolumn1c{\cellcolor{white}}}, %$n-1-k$
  column type={|>{\cellcolor{FarbeUnten}\scriptsize}c|},
  precision=0
},%
% --------------------------
% Übrige Spalten benenen
columns/2/.style = {column name={$0{,}1$},discard if equal={1.0}},
columns/3/.style = {column name={$0{,}2$},discard if equal={1.0}},
columns/4/.style = {column name={$0{,}25$},discard if equal={1.0}},
columns/5/.style = {column name={$0{,}3$},discard if equal={1.0}},
columns/6/.style = {column name={$0{,}4$},discard if equal={1.0}},
columns/7/.style = {column name={$0{,}5$},discard if equal={1.0}},
% --------------------------
% Einsen beseitigen
%discard if equal={1.0}, % ToDo: Wie nur auf columns 1-6 anwenden?
% --------------------------
% "Null Komma" in Tabelle beseitigen
% ToDo....
% --------------------------
% Allgemeine Formatierungen festlegen
 foreach column append style={nSpalte,2,3,4,5,6,7}{column type/.add={>{\scriptsize}}{}},
% Angezeigte Spalten definieren
columns={nSpalte,1,2,3,4,5,6,7,kSymSpalte} 
]{\SumBinVertTab}

\bigskip

%\def\getcell#1#2{
%\pgfplotstablegetelem{#1}{#2}\of{\SumBinVertTab}\pgfplotsretval%
%}
%
%$P(X \leq k) = B(n,p;k) = \getcell{0}{2}$
%
%$P(X = k) = P(X \leq k) - P(X \leq k-1) = B(n,p;k) - B(n,p;k-1)  = ???$
\end{document}

alt text

Eine andere Möglichkeit wäre, an der Stelle eine Rundung mit Hilfe von pgfmath durchzuführen. Da mit \pgfround nicht auf eine bestimmte Anzahl an Nachkommastellen, sondern nur auf Integer gerundet werden kann, muss man den Wert entsprechend skalieren. Die Lösung könnte in obigem Fall beispielsweise so aussehen:

Open in Online-Editor
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \pgfmathparse{ifthenelse(round(##1*10000)==round(#1*10000),0,1)}%
      \ifcase \pgfmathresult
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      \fi
    }
  },
}

Dabei wird auch gleich \pgfifthenelse verwendet, um den Vergleich durchzuführen. Sind die Werte gleich, wird \pgfmathresult so 0, sonst 1. Das Ergebnis ist wie in der Abbildung oben. Die genannten Funktionen von pgfmath sind in der pgf-Anleitung dokumentiert (derzeit Kapitel 89).

Last but not least kann man natürlich auch die Funktion zur Festlegung der Nachkommastellen verwenden, die auch pgfplotstable bei der Ausgabe der Zahlen verwendet, also \pgfmathroundto:

Open in Online-Editor
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \pgfkeys{/pgf/number format/precision=4}%
      \pgfmathroundto{##1}%
      \ifdim \pgfmathresult pt=#1pt
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      \fi
    }
  },
}

oder mit ifthenelse:

Open in Online-Editor
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \pgfkeys{/pgf/number format/precision=4}%
      \pgfmathroundto{##1}%
      \pgfmathparse{ifthenelse(\pgfmathresult==#1,0,1)}%
      \ifcase \pgfmathresult
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      \fi
    }
  },
}

Außerdem liefert pgf auch gleich eine unscharfen Vergleichsoperation für Gleitkommazahlen, die genau den Vergleich durchführen kann, der letztlich auch bereits in meinem ersten Beispiel verwendet wird:

Open in Online-Editor
\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \pgfkeys{/pgf/fpu/rel thresh=5e-5}%
      \pgfmathfloatifapproxequalrel{##1}{#1}{%
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      }{}
    }
  },
}

All das liefert das gleiche Ergebnis wie oben bereits gezeigt. Dokumentiert sind \pgfmathroundto und \pgfmathfloatifapproxequalrel ebenfalls in der pgf-Anleitung, derzeit Kapitel 54.

Permanenter link

beantwortet 20 Jan, 11:04

saputello's gravatar image

saputello
18.4k22352

bearbeitet 21 Jan, 04:15

Super. Danke!

(20 Jan, 11:21) cis

Mit expl3 kann man eine Zahl leicht auf beliebig viele Nachkommastellen runden. Dazu verwendet man einfach round(x,n), wobei x auf n Stellen gerundet wird.

Open in Online-Editor
%\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand \fpcompare { m m }
 {
  \fp_compare:nT { #1 } { #2 }
 }
\ExplSyntaxOff

\pgfplotstableset{
  discard if equal/.style = {
    preproc cell content/.code={
      \fpcompare{round(##1,4) == #1}{%
        \pgfkeyssetvalue{/pgfplots/table/@cell content}{}
      }
    }
  },
}

alt text

Permanenter link

beantwortet 20 Jan, 11:26

Henri's gravatar image

Henri
10.0k31730

bearbeitet 20 Jan, 12:26

Deine Antwort auf die Frage (nicht auf andere Antworten)
Knebel-Vorschau

Folge dieser Frage

Per E-Mail:

Wenn Du Dich anmeldest, kannst Du Updates hier abonnieren

Per RSS:

Antworten

Antworten und Kommentare

Aktuelle Buch-Infos

LaTeX Cookbook

LaTeX Beginners Guide

Limitierter Rabatt ebook
50% Coupon code tDRet6Y

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs füge einfach zwei Leerzeichen an die Stelle ein, an der die neue Zeile sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Zugeordnete Themen:

×185
×11

Frage gestellt: 20 Jan, 10:40

Frage wurde angeschaut: 816 Mal

Zuletzt aktualisiert: 21 Jan, 04:15