Используя ваш пример, вы хотите рассчитать среднее действие для каждого уникального пользователя USER_B:
[,1] [,2]
[1,] 7 0.5
[2,] 8 1.0
[3,] 6 2.0
Это можно сделать с помощью одной строки кода, используя функцию ddply()
в пакете plyr
library(plyr)
ddply(train_data[, -1], .(USER_B), numcolwise(mean))
USER_B ACTION
1 6 2.0
2 7 0.5
3 8 1.0
В качестве альтернативы функция tapply
в базе R делает то же самое:
tapply(train_data$ACTION, train_data$USER_B, mean)
В зависимости от размера вашей таблицы вы можете улучшить время выполнения в 20 разили выше.Вот тест system.time для data.frame с миллионом записей.Ваш алгоритм занимает 116 секунд, ddply () занимает 5,4 секунды, а tapply - 1,2 секунды:
train_data <- data.frame(
USER_A = 1:1e6,
USER_B = sample(1:1e3, size=1e6, replace=TRUE),
ACTION = sample (1:100, size=1e6, replace=TRUE))
yourfunction <- function(){
result <- matrix(0,length(unique(train_data$USER_B)),2)
result[,1] <- unique(train_data$USER_B);
for(i in 1:dim(result)[1]){
temp=train_data[train_data$USER_B%in%result[i,1],]
result[i,2]=sum(temp[,3])/dim(temp)[1]
}
result
}
system.time(XX <- yourfunction())
user system elapsed
116.29 14.04 134.33
system.time(YY <- ddply(train_data[, -1], .(USER_B), numcolwise(mean)))
user system elapsed
5.43 1.60 7.19
system.time(ZZ <- tapply(train_data$ACTION, train_data$USER_B, mean))
user system elapsed
1.17 0.06 1.25