首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R: ecdf优于直方图

R: ecdf优于直方图
EN

Stack Overflow用户
提问于 2015-03-27 05:18:12
回答 6查看 8.4K关注 0票数 4

在R中,使用ecdf我可以绘制经验累积分布函数

代码语言:javascript
复制
plot(ecdf(mydata))

使用hist,我可以绘制数据的直方图

代码语言:javascript
复制
hist(mydata)

如何在同一图中绘制直方图和ecdf?

编辑

我试着做这样的东西

https://mathematica.stackexchange.com/questions/18723/how-do-i-overlay-a-histogram-with-a-plot-of-cdf

EN

回答 6

Stack Overflow用户

发布于 2016-10-18 22:53:50

还有一点晚了,这里有另一个解决方案,它扩展了@Christoph的解决方案,增加了第二个y轴。

代码语言:javascript
复制
par(mar = c(5,5,2,5))
set.seed(15)
dt <- rnorm(500, 50, 10)
h <- hist(
  dt,
  breaks = seq(0, 100, 1),
  xlim = c(0,100))

par(new = T)

ec <- ecdf(dt)
plot(x = h$mids, y=ec(h$mids)*max(h$counts), col = rgb(0,0,0,alpha=0), axes=F, xlab=NA, ylab=NA)
lines(x = h$mids, y=ec(h$mids)*max(h$counts), col ='red')
axis(4, at=seq(from = 0, to = max(h$counts), length.out = 11), labels=seq(0, 1, 0.1), col = 'red', col.axis = 'red')
mtext(side = 4, line = 3, 'Cumulative Density', col = 'red')

诀窍如下:您不需要在绘图中添加一行,而是在顶部绘制另一个绘图,这就是我们需要par(new = T)的原因。然后,您必须稍后添加y轴(否则它将绘制在左侧的y轴上)。

Credits go here (@tim_yates Answer)和there

票数 9
EN

Stack Overflow用户

发布于 2015-03-27 05:37:35

有两种方法可以做到这一点。一种是忽略不同的尺度,并在直方图中使用相对频率。这会导致直方图更难阅读。第二种方法是改变一个或另一个元素的比例。

我怀疑你很快就会对this question感兴趣,尤其是@hadley的回答。

ggplot2单比例尺

这里有一个ggplot2的解决方案。不过,我不确定您是否会对结果感到满意,因为CDF和直方图(计数或相对)处于完全不同的视觉尺度上。注意:此解决方案将数据放在名为mydata的数据帧中,并在x中包含所需的变量。

代码语言:javascript
复制
library(ggplot2)
set.seed(27272)
mydata <- data.frame(x=  rexp(333, rate=4) + rnorm(333))

 ggplot(mydata, aes(x)) + 
     stat_ecdf(color="red") + 
     geom_bar(aes(y = (..count..)/sum(..count..))) 

基数R多尺度

在这里,我将重新调整经验CDF的比例,以便其最大值不是最大值1,而是具有最高相对频率的任何bin。

代码语言:javascript
复制
h  <- hist(mydata$x, freq=F)
ec <- ecdf(mydata$x)
lines(x = knots(ec), 
    y=(1:length(mydata$x))/length(mydata$x) * max(h$density), 
    col ='red')

票数 4
EN

Stack Overflow用户

发布于 2018-05-09 23:27:25

您可以尝试使用第二个轴的ggplot方法

代码语言:javascript
复制
set.seed(15)
a <- rnorm(500, 50, 10)

# calculate ecdf with binsize 30
binsize=30
df <- tibble(x=seq(min(a), max(a), diff(range(a))/binsize)) %>% 
        bind_cols(Ecdf=with(.,ecdf(a)(x))) %>% 
        mutate(Ecdf_scaled=Ecdf*max(a))
# plot
ggplot() + 
  geom_histogram(aes(a), bins = binsize) +
  geom_line(data = df, aes(x=x, y=Ecdf_scaled), color=2, size = 2) + 
  scale_y_continuous(name = "Density",sec.axis = sec_axis(trans = ~./max(a), name = "Ecdf"))

编辑

由于缩放错误,我添加了第二个解决方案,提前计算所有内容:

代码语言:javascript
复制
binsize=30
a_range= floor(range(a)) +c(0,1)

b <- seq(a_range[1], a_range[2], round(diff(a_range)/binsize)) %>% floor() 


df_hist <- tibble(a) %>% 
  mutate(gr = cut(a,b, labels = floor(b[-1]), include.lowest = T, right = T)) %>% 
  count(gr) %>% 
  mutate(gr = as.character(gr) %>% as.numeric()) 

# calculate ecdf with binsize 30
df <- tibble(x=b) %>% 
  bind_cols(Ecdf=with(.,ecdf(a)(x))) %>% 
  mutate(Ecdf_scaled=Ecdf*max(df_hist$n))
  
ggplot(df_hist, aes(gr, n)) + 
   geom_col(width = 2, color = "white") + 
   geom_line(data = df, aes(x=x, y=Ecdf*max(df_hist$n)), color=2, size = 2) +
   scale_y_continuous(name = "Density",sec.axis = sec_axis(trans = ~./max(df_hist$n), name = "Ecdf"))

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29289046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档