这是我的看法(使用百分位等级),它仅假设可以使用单变量系列测量(您的列标题X
)。您可能需要稍微调整一下以使用预先计算的累积频率,但这并不难。
# generate some artificial data
reset
set sample 200
set table 'rnd.dat'
plot invnorm(rand(0))
unset table
# display the CDF
unset key
set yrange [0:1]
perc80=system("cat rnd.dat | sed '1,4d' | awk '{print $2}' | sort -n | \
awk 'BEGIN{i=0} {s[i]=$1; i++;} END{print s[int(NR*0.8-0.5)]}'")
set arrow from perc80,0 to perc80,0.8 nohead lt 2 lw 2
set arrow from graph(0,0),0.8 to perc80,0.8 nohead lt 2 lw 2
plot 'rnd.dat' using 2:(1./200.) smooth cumulative
这会产生以下输出:

当然,您可以根据需要添加任意数量的百分位值;您只需要定义一个新变量,例如perc90
,并请求另外两个arrow
命令,然后用所需的变量(在本例中为 0.9)替换每次出现的0.8
(啊……神奇数字的乐趣!)。
关于上面代码的一些解释:
- 我生成了一个人工数据集,该数据集保存在磁盘上。
- 第 80 个百分位是使用 awk 计算的,但在此之前我们需要
table
删除由(前四行)生成的标题;(我们可以要求 awk 从第 5 行开始,但让我们继续吧。)
- 只保留第二列;
- 对条目进行排序。
- 计算第 80 个百分位数的 awk 命令需要截断,按照此处的建议完成。(在 R 中,我会简单地使用一个函数
trunc(rank(x))/length(x)
来获取百分位数。)
如果你想给 R 一个机会,你可以安全地用对 R 的调用来替换一长串 sed/awk 命令,比如
Rscript -e 'x=read.table("~/rnd.dat")[,2]; sort(x)[trunc(length(x)*.8)]'
假设rnd.dat
在您的主目录中。
旁注:如果你可以不使用 gnuplot,这里有一些 R 命令可以制作这种图形(即使不使用该quantile
函数):
x <- rnorm(200)
xs <- sort(x)
xf <- (1:length(xs))/length(xs)
plot(xs, xf, xlab="X", ylab="Cumulative frequency")
## quick outline of the 80th percentile rank
perc80 <- xs[trunc(length(x)*.8)]
abline(h=.8, v=perc80)
## alternative solution
plot(ecdf(x))
segments(par("usr")[1], .8, perc80, .8)
segments(perc80, par("usr")[3], perc80, .8)
