注意,文章中所有
{ { } }
{ % % }
中间没有空格
变量
用{ { } }
来修饰变量,内部的值会被渲染成文本。比如 我有{ { 1 + 1 } }个苹果
会被渲染成 我有2个苹果
。
通常我们会提前设置好一些变量,比如,我们在写模板的时候,为了方便起见,可以先设pro_code=44
,即广东省的省代码,这些变量的设置可以在word的常量表里。那么我们在需要用到省代码的地方,可以写成{ { pro_code } }
,如此便能在不同的省报告中使用不同的省代码了。
计算
我们除了可以设置一些常量(如pro_code
)之外,我们还可以计算一些临时变量。比如a = 500*600
,这样,我们就得到一个变量2,他的值为500和600的乘积。除此以外,我们更常用的是如下这种形式的计算:
1 | a2=V("maths_level")|table("4stu")|select({"province":pro_code})|which(2)|percent|format({"decimal":1,"multi":100}) |
我们分别来说一下其中用到的一些方法。
Variable 和 table
表示变量的符号。上面的例子中,等号后面的式子,开头一个V表示variable
,这是为了识别数据库中的变量。后面的参数就是变量名。Variabel
后面的 table
指明变量来自于哪一个表。为了方便起见,这两种写法是等价的:
1 | V("maths_level")|table("4stu") <==> V("maths_level", "4stu") |
select
select
是对数据的选择。上面的例子指明了我们的数据限定在一个省。如果要计算全国数据,直接去掉select及其参数即可。如果需要使用多个筛选条件,比如要选择广东省的男生数据,那么可以用逗号隔开两个条件,写成如下形式:(province 和 gender都是数据库中的变量,他们都需要用引号包裹起来)
1 | select({"province":pro_code, "gender":1}) |
which
which
只有在计算百分比的时候有用,因为他指的是计算谁的百分比。上例中计算的是maths_level
为2的百分比。
percent & mean
这两个函数都是指明计算方法,顾名思义,前者计算百分比,后者计算平均值。
format
顾名思义,format
是用来描述数据格式的。参数decimal
表明小数位数,multi
表明乘数,按照上例来说,percent方法的计算结果都在(0,1)之间,所以我们让结果乘以100,保留1位小数, 另外再加上一个百分号。写法就是:(decimal、multi和suffix的前后顺序不影响结果)
1 | format({"decimal":1,"multi":100,"suffix":"%"}) |
其实你可以省略format,这时候系统会使用默认的配置,保留一位小数。百分比的结果会乘以100以后再保留一位小数。
有一个问题需要指出,就是你在计算一个变量的时候,什么时候保留小数位数你得自己设置。例如,如下两种写法是不同的:
第一种写法:先保留一位小数,再相加
1 | a2=V("maths_level")|table("4stu")|select({"province":pro_code})|which(2)|percent|format({"decimal":1,"multi":100}) |
第二种写法:先相加再保留1位小数
1 | a2=V("maths_level")|table("4stu")|select({"province":pro_code})|which(2)|percent |
groupby
groupby
是将数据分组,分组后再计算,这样每个组都会得到一个结果。比如:
1 | V("maths","4stu")|groupby("gender")|mean |
这是计算两种性别下maths的平均值。
mi & ma
经常配合groupby使用,求最小值和最大值。因为groupby可以计算得到多个值,在多个值里面选择最大值和最小值就用ma
和mi
。
1 | V("maths","4stu")|groupby("gender")|mean|mi |
逻辑判断
逻辑判断语句的基本写法是:
1 | { % if a==b % } |
注意,逻辑判断语句用到的符号是{ % ... % }
。其中 if 和 end 标明语句的开始和结尾,中间可以用elif增加判断语句,它是可选的,你可以不使用它,只用if ... else ... end
, 你也可以用多个elif。还有就是,虽然我们写了很多行,但是最终渲染得到的内容是没有换行的,也就是任何换行符都会被删除。
实战
在报告中,经常用到非常复杂的计算。例如看下面在报告模板中的真实写法:
1 | ======Variables======= |
其中有两个特殊的行======Variables=======
和=======Content========
,他们是分隔符,在两行中间可以定义各种用到的变量,这些变量不会被渲染。而content下面的内容是真正会被渲染的部分,但是这部分又用到了上面定义的变量。
图表
序列
word中的图表都是由数据序列构成的,数据序列可以看成是一列数值,比如(1, 2, 3, 4)
就是一个数据序列,我们的系统中,用如下方法表达一个序列:
1 | v("maths_level")|table("4stu")|select({"province":pro_code})|percent|format({"decimal":1,"multi":100}) |
以上代码中,我们只使用选择了某个省的数据,指明了变量maths_level,并没有指明which,这样就会返回maths_level的所有水平的百分比。百分比会按照水平值从小到大排列,最终的结果就类似于(1.2, 3.4, 90.0, 5.2)
还有一种方法是使用groupby, 它的作用是将数据分组。例如:
1 | v("maths_level")|table("4stu")|select({"province":pro_code})|groupby("gender_new")|which(1)|percent|format({"decimal":1,"multi":100}) |
以上代码中,groupby指明数据按照性别分组,这样计算结果会得到类似这样的结果(90.0, 5.2)
,两个数分别表示男生和女生的maths_level为1的百分比。
另有一种特殊的情况是,一个数据序列由多用算法计算得到,比如
1 | v("maths_level")|table("4stu")|select({"province":pro_code})|which(1)|groupby("school_loc_new")|percent|format({"decimal":1,"multi":100})| merge |v("maths_level")|table("8stu")|select({"province":pro_code})|which(1)|groupby("school_loc_new")|percent|format({"decimal":1,"multi":100}) |
以上代码使用了merge算法,将前后两种计算结果合并在一起构成一个序列。merge之前计算结果为四年级的数据,如(4.5, 6.5, 2.4)
,之后计算的是八年级的数据,结果为(55.4, 34.2, 42.3)
,合并之后为(4.5, 6.5, 2.4, 55.4, 34.2, 42.3)