R-подобный подход к усреднению по ячейке гистограммы

как человек, переходящий с Matlab, я хотел бы получить какой-либо совет для более эффективного способа найти среднее значение значений DepDelay, индексы (indxs) которых попадают в ячейки гистограммы (края). В 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])
  }
}

Я знаю, что использование циклов for в R потенциально чревато проблемами, но я задаю этот вопрос в интересах повышения эффективности кода.

Конечно. Несколько фрагментов соответствующих векторов:

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

Спасибо.

БСЛ


person Benjamin Levy    schedule 06.04.2015    source источник
comment
Можете ли вы показать нам DepDelay, чтобы сделать это воспроизводимым?   -  person Thomas    schedule 06.04.2015
comment
Конечно. Несколько фрагментов соответствующих векторов: 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. помощь? Спасибо.   -  person Benjamin Levy    schedule 06.04.2015
comment
Пожалуйста, отредактируйте их в своем вопросе в воспроизводимом формате.   -  person Thomas    schedule 06.04.2015


Ответы (1)


В R есть много способов сделать это, все они включают вариации стратегии «разделить-применить-объединить» (разделить данные на группы, применить функцию к каждой группе, объединить результаты по группам обратно в один фрейм данных).

Вот один из методов с использованием пакета 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:

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

aggregate(DepDelay ~ bins, FUN=mean, data=dat)
person eipi10    schedule 06.04.2015