R中的对数概率图表

3

我相信这很简单,但我一直在尝试找出如何在R中实现这一点。

我有一些数据,想要拟合到一个幂定律分布上。为了做到这一点,你需要在对数-对数累积概率图上绘制数据。y轴是数据的频率的对数(或者说是对数概率),x轴是值的对数。如果它是一条直线,那么它就符合幂定律分布,而斜率则决定了幂定律参数。

如果我想要数据的频率,我可以使用ecdf()函数:

我的数据集叫做Profits.negative,它只是一个长长的负交易利润列表(我已经将所有的负数转换成正数,以避免在后面出现对数问题)。

所以我可以输入:

plot(ecdf(Profits.negative))

我得到了一个方便的经验累积分布函数,并进行了绘图。现在我只需要将两个轴转换为对数刻度即可。我可以处理x轴:

Profits.negative.logs <- log(Profits.negative)
plot(ecdf(Profits.negative.logs))

快要完成了!我只需要想办法记录y轴!但是我似乎做不到,并且我也无法提取ecdf对象中的数字。有人能帮忙吗?

我知道有power.law.fit函数,但那只是估计参数-我想绘制数据并查看是否对齐。


4
如果您包含正在使用的数据,您可能会得到更多的帮助。这篇文章在这方面非常有帮助:https://dev59.com/eG025IYBdhLWcg3whGSx#5963610 - Andy Barbour
3个回答

6

您可以使用poweRlaw软件包来适应和绘制幂律分布曲线。以下是一个例子。首先,我们从重尾分布生成一些数据:

set.seed(1)
x = round(rlnorm(100, 3, 2)+1)

下一步,我们加载包并创建数据对象和显示对象:
library(poweRlaw)
m = displ$new(x)

我们可以估计出xmin和缩放参数:
est = estimate_xmin(m))

并设置参数

m$setXmin(est[[2]])
m$setPars(est[[3]])

然后绘制数据并添加拟合曲线:

plot(m)
lines(m, col=2)

获得如下内容: enter image description here

这真的很有用。我正在尝试手动复制您的绘图,类似于下面 rafa 的解决方案。我该如何查看上面 m 的源代码(在 plot(m) 中确切输入了什么),如果可能的话,我想在您的代码中看到与 rafa 的 k <- seq_along(x) 相当的东西?getAnywhere(displ) 没有显示给我。我正在努力弄清楚为什么他(你也是吗?)在 x 轴上使用 k 而不是 log(x)?谢谢 - user63230
1
如果您执行 dd = plot(m),则会返回 x 和 y 值。这有帮助吗? - csgillespie

2
首先是数据生成(其实这部分是你的工作):
set.seed(1)
Profits.negative <- runif(1e3, 50, 100) + rnorm(1e2, 5, 5)

记录日志和 ecdf

Profits.negative.logs <- log(Profits.negative)
fn <- ecdf(Profits.negative.logs)

ecdf返回函数,如果你想从中提取某些信息 - 查看函数的闭包是一个很好的主意:

ls(environment(fn))
# [1] "f"      "method" "n"      "nobs"   "x"      "y"      "yleft"  "yright"

现在,我们可以访问xy

x <- environment(fn)$x
y <- environment(fn)$y

可能这正是你所需要的。实际上,plot(fn)plot(x,y,type="l")几乎展示了相同的结果。如果要对y轴取对数,只需要:

plot(x,log(y),type="l")

1
这里是使用ggplot2的方法:
library(ggplot2)

# data
  set.seed(1)
  x = round(rlnorm(100, 3, 2)+1)

# organize data into a df
  df <- data.frame(x = sort(x, decreasing = T),
                   pk <- ecdf(x)(x),
                   k <- seq_along(x))

# plot
  ggplot(df, aes(x=k, y= pk)) + geom_point(alpha=0.5) + 
    coord_trans(x = 'log10', y = 'log10') +
    scale_x_continuous(breaks = trans_breaks("log10", function(x) 10^x), labels = trans_format("log10", math_format(10^.x))) +
    scale_y_continuous(breaks = trans_breaks("log10", function(x) 10^x), labels = trans_format("log10", math_format(10^.x)))

enter image description here


为什么在尝试绘制对数对数图时,您要在x轴上绘制log(k) seq_along(x)而不是log(x)?请参考我在Colins答案下面的评论。谢谢。 - user63230

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接