2015-05-23 8 views
3

у меня есть 25-летний набор данных, который выглядит примерно следующим образом:Как избежать для петель с несколькими критериями, в функции которых()

 date name  value tag 
1 2014-12-01 f -0.338578654 12 
2 2014-12-01 a 0.323379254 4 
3 2014-12-01 f 0.004163806 9 
4 2014-12-01 f 1.365219477 2 
5 2014-12-01 l -1.225602543 7 
6 2014-12-01 d -0.308544089 9 

Это, как повторить его:

set.seed(9) 
date <- rep(seq(as.Date("1990-01-01"), as.Date("2015-01-1"), by="months"), each=50) 
N <- length(date) 
name <- sample(letters, N, replace=T) 
value <- rnorm(N) 
tag <- sample(c(1:50), N, replace=T) 
mydata <- data.frame(date, name, value, tag) 
head(mydata) 

Я хотел бы создать новую матрицу, которая хранит значения, которые удовлетворяют нескольким критериям. Например, сумма значений, которые имеют значение j и a тегi. Я использую два for-loops и функцию which() для фильтрации правильных значений. Например:

S <- matrix(data=NA, nrow=length(unique(mydata$tag)), ncol=length(unique(mydata$name))) 
for(i in 1:nrow(S)){ 
    for (j in 1:ncol(S)){ 
    foo <- which(mydata$tag == unique(mydata$tag)[i] & mydata$name == unique(mydata$name)[j]) 
    S[i,j] <- sum(mydata$value[foo]) 
    } 
} 

Это нормально для небольших наборов данных, но слишком медленно для больших. Можно ли избежать циклов for-loops или ускорить процесс?

ответ

3

Вы можете использовать dcast из пакета reshape2 с пользовательской функции суммировать ваши значения:

library(reshape2) 
dcast(mydata, name~tag, value.var='value', fun.aggregate=sum) 

Или просто xtabs, базовые R:

xtabs(value~name+tag, mydata) 

Некоторые тест:

funcPer = function(){ 
    S <- matrix(data=NA, nrow=length(unique(mydata$tag)), ncol=length(unique(mydata$name))) 
    for(i in 1:nrow(S)){ 
     for (j in 1:ncol(S)){ 
     foo <- which(mydata$tag == unique(mydata$tag)[i] & mydata$name == unique(mydata$name)[j]) 
     S[i,j] <- sum(mydata$value[foo]) 
     } 
    } 
} 

colonel1 = function() dcast(mydata, name~tag, value.var='value', fun.aggregate=sum) 

colonel2 = function() xtabs(value~name+tag, mydata) 

#> system.time(colonel1()) 
# user system elapsed 
# 0.01 0.00 0.01 
#> system.time(colonel2()) 
# user system elapsed 
# 0.05 0.00 0.05 
#> system.time(funcPer()) 
# user system elapsed 
# 4.67 0.00 4.82 
+0

Спасибо! Так оно и было. – Per

+0

удовольствие помочь! –

 Смежные вопросы

  • Нет связанных вопросов^_^