我想进行计算来绘制图表。但我找不到获取已加载数据文件中某一行某一列的值的方法。
如何获取当前行上方 14 行单元格的值?对于前一行,有\prevrowno{1}
,其中“1”表示列号。
我在 MWE 中写了几行伪代码。但我不知道如何获取可用的代码\GetRowVal
。我见过这个回答,但未能制定出可行的解决方案。
我真的希望我在这里的描述清楚。请询问,我很乐意提供更多解释。
我的 MWE:
\documentclass[paper=landscape, DIV=30]{scrarticle}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{filecontents}{Verdoppelungszeit.csv}
Tag BRD
2020-03-10 654
2020-03-11 1089
2020-03-12 1892
2020-03-13 2576
2020-03-14 3421
2020-03-15 4195
2020-03-16 5433
2020-03-17 7156
2020-03-18 8198
2020-03-19 10999
2020-03-20 13957
2020-03-21 16662
2020-03-22 18610
2020-03-23 22672
2020-03-24 27436
2020-03-25 31554
2020-03-26 36508
2020-03-27 42288
2020-03-28 48582
2020-03-29 52547
2020-03-30 57298
2020-03-31 61913
2020-04-01 67366
2020-04-02 73522
2020-04-03 79696
2020-04-04 85778
2020-04-05 91714
\end{filecontents}
\pgfplotsset{compat=1.17}
\usepgfplotslibrary{dateplot}
\begin{document}
%\pgfplotstableread{Verdoppelungszeit.csv}\loadedtable
%%% Does not work!
%\newcommand{\GetRowVal}[1]{%
% Value of Column 1, #1 Rows abvoe Current Row
%}
\newcommand{\Subtraction}[1]{%
\thisrowno{1} - \GetRowVal{#1}
}
\pgfplotstableset{% WORKS
create on use/brdoppel/.style=
{create col/expr={ln(2)/(ln((\thisrowno{1}-\prevrowno{1})/\prevrowno{1}+1))}}
}
%\pgfplotstableset{% HOW CAN I DO THIS?
% create on use/brdoppelALT/.style=
% {create col/expr={ln(2)/(ln((\thisrowno{1}-\prevrowno{1})/
% \Subtraction{14}+1))}}
%}
\begin{tikzpicture}
\begin{semilogyaxis}[
width=20cm,
unbounded coords=discard,
xlabel=Datum, grid=major,
date coordinates in=x,
xtick = data,
x tick label style={rotate=45,anchor=north east},
]
\addplot [blue, ultra thick]
table [%
x=Tag, y=BRD, xlabel style={font=\sffamily}]{Verdoppelungszeit.csv};
\addplot+ [blue, mark=*,mark options={fill=white}, thin,
restrict y to domain=0.1:inf]
table [x=Tag, y=brdoppel]{Verdoppelungszeit.csv};
%% Does not work!
%\addplot+ [yellow, mark=*,mark options={fill=white}, thin,
% restrict y to domain=0.1:inf]
% table [x=Tag, y=brdoppelALT]{Verdoppelungszeit.csv};
\end{semilogyaxis}
\end{tikzpicture}
\end{document}
一个非常好的额外功能是进行测试,如果存在当前行上方 14 行(例如),则如果不存在,则整个术语的计算就没有结果。
编辑
评论中的问题:你想计算什么。简短回答:参见这里
我正在尝试计算感染人数翻倍的时间。公式是
ln(2) / ln(q),其中 q = 1 + p/100
数据来自韋科页。
现在,几周过去了,计算结果非常具有误导性,因为恢复健康的人数不见了。3 月初被感染的人要么健康,要么……然而,他们不会感染任何人,所以在我看来,继续将他们考虑在内是错误的。
因此,我想“抹去”所有曾经被感染但将来不会感染任何人的人的数量,因为他们感染的时间太久了。
一种简单的方法(记住:这不是科学,而是在摆弄数字)似乎是取新感染人数(这是\thisrowno{1} - \prevrowno{1}
),然后减去在某个时间之前(比如说 14 天)感染的所有人数。我们得到一个粗略的数字,有多少人可能具有传染性今天。这是计算加倍所需时间的基数。
要减去 14 天前被感染的人数,我只需查看数据,但我无法将其输入到代码中!
答案1
pgfplotstable 只能访问前后行中的值。您可以自然地将列移动 14 次以访问其他值,但我会将这些值存储在 expl3 序列中,然后您可以访问任何值并进行任何您想要创建新列的计算:
\documentclass[paper=landscape, DIV=30]{scrarticle}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{filecontents}{Verdoppelungszeit.csv}
Tag BRD
2020-03-10 654
2020-03-11 1089
2020-03-12 1892
2020-03-13 2576
2020-03-14 3421
2020-03-15 4195
2020-03-16 5433
2020-03-17 7156
2020-03-18 8198
2020-03-19 10999
2020-03-20 13957
2020-03-21 16662
2020-03-22 18610
2020-03-23 22672
2020-03-24 27436
2020-03-25 31554
2020-03-26 36508
2020-03-27 42288
2020-03-28 48582
2020-03-29 52547
2020-03-30 57298
2020-03-31 61913
2020-04-01 67366
2020-04-02 73522
2020-04-03 79696
2020-04-04 85778
2020-04-05 91714
\end{filecontents}
\pgfplotsset{compat=1.17}
\usepgfplotslibrary{dateplot}
\pgfplotstableread{Verdoppelungszeit.csv}\datatable
\ExplSyntaxOn
\seq_new:N\l_keks_data_seq
\pgfplotstableforeachcolumnelement{BRD}\of\datatable\as\yvalue
{
\seq_put_right:NV \l_keks_data_seq {\yvalue}
}
\pgfplotstablecreatecol[create~col/assign/.code={%
\int_compare:nNnTF {\pgfplotstablerow-14}<1
{
\tl_set:Nx \entry{0}
}
{
\tl_set:Nx \entry{\seq_item:Nn \l_keks_data_seq {\pgfplotstablerow-14}}
}
\pgfkeyslet{/pgfplots/table/create~col/next~content}\entry
}]{shift14}\datatable
\pgfplotstablecreatecol[create~col/assign/.code={%
\tl_set:Nx \entry{\fp_eval:n{\seq_item:Nn \l_keks_data_seq {{\pgfplotstablerow+1}/2}}}
\pgfkeyslet{/pgfplots/table/create~col/next~content}\entry
}]{half}\datatable
\ExplSyntaxOff
\begin{document}
\pgfplotstabletypeset[string type]\datatable
\end{document}
答案2
绘制一些“延迟”数据点非常容易。诀窍是定义一个element
返回表元素的 pgf 函数。此函数可用于以下构造:
y expr={element(\coordindex,1)-element(\coordindex-14,1)}
\getelem
该函数是宏的一个几乎简单的实现,其微妙之处在于它涉及由和整数开启的pgfplotstable
相互作用。fpu
fpu
以下绘制了原始数据和延迟版本。它还计算了倍增时间,即在给定日期病例数翻倍所需的时间。它们有两个版本,一个使用全部病例数,另一个仅查看过去 14 天内的病例。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{filecontents}{Verdoppelungszeit.csv}
Tag BRD
2020-03-10 654
2020-03-11 1089
2020-03-12 1892
2020-03-13 2576
2020-03-14 3421
2020-03-15 4195
2020-03-16 5433
2020-03-17 7156
2020-03-18 8198
2020-03-19 10999
2020-03-20 13957
2020-03-21 16662
2020-03-22 18610
2020-03-23 22672
2020-03-24 27436
2020-03-25 31554
2020-03-26 36508
2020-03-27 42288
2020-03-28 48582
2020-03-29 52547
2020-03-30 57298
2020-03-31 61913
2020-04-01 67366
2020-04-02 73522
2020-04-03 79696
2020-04-04 85778
2020-04-05 91714
\end{filecontents}
\pgfplotsset{compat=1.17}
\usepgfplotslibrary{dateplot}
\begin{document}
\pgfplotstableread{Verdoppelungszeit.csv}\mydata
\pgfplotstablegetrowsof{\mydata}%
\pgfmathtruncatemacro{\numrows}{\pgfplotsretval}%
\pgfmathdeclarefunction{element}{2}{\begingroup
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathtruncatemacro{\myindex}{max(0,#1)}%
\pgfmathtruncatemacro{\mycol}{#2}%
\pgfplotstablegetelem{\myindex}{[index]\mycol}\of\mydata%#1=row, #2=column
\edef\pgfmathresult{\pgfplotsretval}%
\pgfmathsmuggle\pgfmathresult
\endgroup}
\begin{tikzpicture}
\begin{semilogyaxis}[
width=20cm,
unbounded coords=discard,
xlabel=Datum, grid=major,
date coordinates in=x,
xtick = data,
x tick label style={rotate=45,anchor=north east},
legend style={at={(0.01,0.99)},anchor=north west,font=\sffamily,
legend cell align=left}
]
\addplot [blue, ultra thick]
table [%
x=Tag, y=BRD, xlabel style={font=\sffamily}]{Verdoppelungszeit.csv};
\addlegendentry{F\"alle}
\addplot [red, ultra thick]
table [%
x=Tag, y=BRD, xlabel style={font=\sffamily},
y expr={element(\coordindex,1)-element(\coordindex-14,1)}]{Verdoppelungszeit.csv};
\addlegendentry{Neue F\"alle (weniger als 14 Tage alt)}
\addplot [blue, mark=*,mark options={fill=white}, thin]
table [x=Tag,
y expr={ln(2)/ln(1+(element(\coordindex,1)-element(\coordindex-1,1))%
/element(\coordindex,1))}]{Verdoppelungszeit.csv};
\addlegendentry{Verdoppelungszeit}
\addplot [red, mark=*,mark options={fill=white}, thin]
table [x=Tag,
y expr={ln(2)/ln(1+(element(\coordindex,1)-element(\coordindex-1,1))%
/(element(\coordindex,1)-element(\coordindex-14,1)))}]{Verdoppelungszeit.csv};
\addlegendentry{Verdoppelungszeit von neuen F\"allen}
\end{semilogyaxis}
\end{tikzpicture}
%% ADDENDUM
\pgfmathdeclarefunction{melement}{2}{\begingroup
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathtruncatemacro{\myindex}{#1}%
\pgfmathtruncatemacro{\mycol}{#2}%
\ifnum\myindex<0
\edef\pgfmathresult{0}%
\else
\pgfplotstablegetelem{\myindex}{[index]\mycol}\of\mydata%#1=row, #2=column
\edef\pgfmathresult{\pgfplotsretval}%
\fi
\pgfmathsmuggle\pgfmathresult
\endgroup}
\pgfplotstablenew[
% define how the 'new' column shall be filled:
create on use/data/.style={create col/expr={%
melement(\pgfplotstablerow,1)}},
create on use/shifted data/.style={create col/expr={%
melement(\pgfplotstablerow-14,1)}},
columns={data,shifted data}]
{\numrows}
\loadedtable
\pgfplotstabletypeset[columns={data,shifted data}]\loadedtable
\end{document}
还请注意,如附录所示,上述函数类型的函数element
也可以用于排版表格。