通过直方图 bin 进行平均的类似 R 的方法
An R-like approach to averaging by histogram bin
作为一个从 Matlab 过渡的人,我希望得到任何建议,以更有效地找到其索引 (indxs) 落在直方图箱 (edges) 内的 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[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
在 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)
作为一个从 Matlab 过渡的人,我希望得到任何建议,以更有效地找到其索引 (indxs) 落在直方图箱 (edges) 内的 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[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
在 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)