Взятие строки означает на основе разбиения столбцов - PullRequest
3 голосов
/ 31 марта 2012

У меня есть матрица mat и я хочу вычислить среднее значение столбцов на основе групповой переменной gp.

mat<-embed(1:5000,1461)
gp<-c(rep(1:365,each=4),366)

Для этого я использую следующее

colavg<-t(aggregate(t(mat),list(gp),mean))

Но это занимает намного больше времени, чем я ожидаю.

Есть предложения по ускорению работы кода?

Ответы [ 2 ]

2 голосов
/ 31 марта 2012

Вот быстрый алгоритм, который я прокомментировал в коде.

system.time({

# create a list of column indices per group
gp.list    <- split(seq_len(ncol(mat)), gp)

# for each group, compute the row means
means.list <- lapply(gp.list, function(cols)rowMeans(mat[,cols, drop = FALSE]))

# paste everything together
colavg     <- do.call(cbind, means.list)

})
#    user  system elapsed 
#    0.08    0.00    0.08 
1 голос
/ 31 марта 2012

Вы можете использовать функцию применения, например, из превосходного пакета plyr:

# Create data
mat<-embed(1:5000,1461)
gp<-c(rep(1:365,each=4),366)

# Your code
system.time(colavg<-t(aggregate(t(mat),list(gp),mean)))

library(plyr)
# Put all data in a data frame
df <- data.frame(t(mat))
df$gp <- gp

# Using an apply function
system.time(colavg2 <- t(daply(df, .(gp), colMeans)))

Выход:

> # Your code
> system.time(colavg<-t(aggregate(t(mat),list(gp),mean)))
   user  system elapsed 
 134.21    1.64  139.00 

> # Using an apply function
> system.time(colavg2 <- t(daply(df, .(gp), colMeans)))
   user  system elapsed 
  52.78    0.06   53.23 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...