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 '16, 16:40

cis's gravatar image

cis
9.5k75452491
Akzeptiert-Rate: 29%

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 '16, 17: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 '16, 17:04

saputello's gravatar image

saputello
11.1k154365
Akzeptiert-Rate: 51%

bearbeitet 21 Jan '16, 10:15

Super. Danke!

(20 Jan '16, 17: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 '16, 17:26

Henri's gravatar image

Henri
15.7k133943
Akzeptiert-Rate: 46%

bearbeitet 20 Jan '16, 18:26

Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

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ügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×254
×39

gestellte Frage: 20 Jan '16, 16:40

Frage wurde gesehen: 6,711 Mal

zuletzt geändert: 21 Jan '16, 10:15