2015-01-27 2 views
-1

Я воспроизвел в R симуляцию, которая была первоначально выполнена в Stata. Я использовал «для» циклов, так как это единственный способ, которым я знаю, как сделать эту работу. Это займет довольно много времени, поэтому я хотел бы использовать одну из команд «apply», чтобы узнать, быстрее ли это, но я не могу понять, как это сделать. Может ли кто-нибудь помочь? Вот код:Использование для симуляции вместо вложенных циклов

simdiffuse <- function(a, b, c, d) { 

    endo <- 1/a  # innovation endogenous effect 
    endomacro <- 1/b # category endogenous effect 
    appeal <- c  # innovation's ex ante appeal 
    ninnov <- d  # number of innovations in category 

    results <- data.frame(catdensity = rep(0:ninnov, each = 25), t = 1:25, endo = endo, endomacro = endomacro, appeal = appeal, adopt = NA)  

    prop <- rnorm(1000) 
    diff <- data.frame(prop) 
    diff$adopt <- 0 
    diff$adopt[1:5] <- 1 

    for (catdensity in 0:ninnov) { 
    diff$adopt <- 0 
    diff$adopt[1:5] <- 1 

    for (t in 1:25) { 
     results[results$catdensity == catdensity & results$t == t,]$adopt <- mean(diff$adopt) 
     for (obs in 1:nrow(diff)) { 
     if(appeal+(mean(diff$adopt)*endo)+(catdensity*endomacro) > rnorm(1, diff[obs,]$prop)) diff[obs,]$adopt <- 1 
     } 
    } 
    } 
    return(results) 
} 

results <- simdiffuse(.2, 20, -3, 60) 
+2

'apply' функции семьи не являются обязательно быстрее, чем цикл for. Медленность в цикле часто связана с ростом вашего массива или матрицы или всего внутри цикла, а не с предварительным распределением объекта с правильным размером. Вы пытались запустить [Rprof] (https://stat.ethz.ch/R-manual/R-patched/library/utils/html/Rprof.html), чтобы узнать, где ваш код медленный. – jraab

ответ

1

Вы можете улучшить скорость вашей функции с помощью data.table. Однако вам все равно придется использовать петли for (что не так уж плохо).

library(data.table) 
simdiffuse <- function(a, b, c, d) { 

    endo <- 1/a  # innovation endogenous effect 
    endomacro <- 1/b # category endogenous effect 
    appeal <- c  # innovation's ex ante appeal 
    ninnov <- d  # number of innovations in category 

    results <- data.table(catdensity = rep(0:ninnov, each = 25), t = 1:25, 
         endo = endo, endomacro = endomacro, appeal = appeal, 
         adopt = as.numeric(NA))  


    for (cc in 0:ninnov) { 
    diff <- data.table(prop = rnorm(1000), adopt = c(rep(1,5), rep(0, 995))) 
    for (tt in 1:25) { 
     results[catdensity == cc & t == tt, adopt := diff[, mean(adopt)]] 
     diff[, rr := rnorm(1, prop), by="prop"] 
     diff[appeal + mean(adopt) * endo + cc * endomacro > rr, adopt := 1] 
    } 
    } 
    return(results) 
} 

results <- simdiffuse(.2, 20, -3, 60) 

у меня не было достаточно времени, чтобы ждать, пока ваш код не выполняется, а вот график adopt VS. t, что я получаю:

adopt vs. t, grouped by catdensity

+0

Спасибо за это. Я боролся с идеей, что мне пришлось использовать одну из функций «apply», поэтому хорошо знать, что это не так, и увидеть другой способ, с помощью которого я могу улучшить скорость моего кода. –

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