通过直方图bin进行平均的类似R的方法

时间:2015-04-06 14:21:47

标签: r matlab histogram average bins

作为一个从Matlab过渡的人,我希望有任何建议可以更有效地找到其索引(indxs)落在直方图区间(边缘)内的DepDelay值的平均值。在Matlab和我当前的R脚本中,我有以下命令:

edges       =   seq( min(t), max(t), by = dt )
indxs       =   findInterval( t, edges,all.inside=TRUE )
listIndx    =   sort( unique( indxs ) )
n           =   length( edges )
avgDelay    =   rep( 1, n) * 0
for (i in 1 : n ){
  id = listIndx[i]
  jd = which( id == indxs )
  if ( length(jd) > minFlights){
    avgDelay[id] = mean(DepDelay[jd])
  }
}

我知道在R中使用for循环是一个潜在的问题,但我提出这个问题是为了提高代码效率。

不确定。相关载体的几个片段:

DepDelay[1:20] = [1] -4 -4 -4 -9 -6 -7 -1 -7 -6 -7 -7 -5 -8 -3 51 -2 -1 -4 -7 -10

和关联的indxs值:

indxs[1:20] = [1] 3 99 195 291 387 483 579 675 771 867 963 1059 1155 1251 1351 1443 1539 1635 1731 1827 

minFlights = 3

谢谢。

BSL

1 个答案:

答案 0 :(得分:3)

在R中有很多方法可以做到这一点,所有这些都涉及" split-apply-combine"策略(将数据拆分为组,将功能应用于每个组,将组合结果组合回单个数据框)。

这是使用dplyr包的一种方法。我已经创建了一些虚假数据用于说明,因为您的数据不是一种易于重现的形式:

library(dplyr) 

# Create fake data
set.seed(20)
dat = data.frame(DepDelay = sample(-50:50, 1000, replace=TRUE))

# Bin the data
dat$bins = cut(dat$DepDelay, seq(-50,50,10), include.lowest=TRUE)

# Summarise by bin
dat %>% group_by(bins) %>%
  summarise(count = n(),
            meanByBin = mean(DepDelay, na.rm=TRUE))

        bins count  meanByBin
1  [-50,-40]   111 -45.036036
2  (-40,-30]   110 -34.354545
3  (-30,-20]    95 -24.242105
4  (-20,-10]    82 -14.731707
5    (-10,0]    92  -4.304348
6     (0,10]   109   5.477064
7    (10,20]    93  14.731183
8    (20,30]    93  25.182796
9    (30,40]   103  35.466019
10   (40,50]   112  45.696429

data.table是此类任务的另一个绝佳方案:

library(data.table)

datDT = data.table(dat)
setkey(datDT, bins)

datDT[, list(count=length(DepDelay), meanByBin=mean(DepDelay, na.rm=TRUE)), by=bins]

这里有两种计算基数R中bin的平均值的方法:

tapply(dat$DepDelay, dat$bins, mean)

aggregate(DepDelay ~ bins, FUN=mean, data=dat)