Home > Mobile >  Saving out from a model in a for loop in r
Saving out from a model in a for loop in r

Time:11-18

I have a dataframe like this one

  ourmodel difference new_topic
1        2 0.08233167         1
2        3 0.07837389         2
3        1 0.15904427         3
4        3 0.05716799         4
5        1 0.13388058         3
6        3 0.09156650         3

and I wish to save each output from the model in the variable out. My approach doesn't seem to work - can anyone see what I'm doing wrong? This is how I do:

library(rethinking)

out <- list()

for (i in unique(singo$new_topic)) {
  i <- ulam(
    alist(
        difference ~ dnorm(mu, sigma),
        mu <- a[ourmodel],
        a[ourmodel] ~ dnorm(0.40, 0.15) ,
        sigma ~ dexp(2) 
    ), data = final, chains = 4, cores = 4)
  out[[i]] <- precis(i, depth = 2)
}

I get the following error

Error in out[[i]] <- precis(i, depth = 2) : invalid subscript type 'S4'

CodePudding user response:

You're making 2 mistakes:

1. You are iterating across S4 objects, rather than integers.

Rather than

for (i in unique(singo$new_topic))

You want

max_i <- length(unique(singo$new_topic))
for (i in 1:max_i)

The error you are getting is because you are iterating over the elements of singo and trying to subset with them, rather than with an integer.

This example might make the nature of the error clearer:

animals <- c("cow", "pig", "sheep")

## This works
for(i in 1:length(animals)){
  print(animals[[i]])
}
#> [1] "cow"
#> [1] "pig"
#> [1] "sheep"

## This also works
for(i in animals){
  print(i)
}
#> [1] "cow"
#> [1] "pig"
#> [1] "sheep"

## This does not
for(i in animals){
  print(animals[[i]])
}
#> Error in animals[[i]]: subscript out of bounds

Created on 2022-11-18 with reprex v2.0.2

2. You are overwriting i

If you want to use i to subset your list, you should not overwrite the value of i in the first line of your list. So do something like:

for(i in 1:max_i){
## don't assign to i here:
j <- ulam(
## some code 
)

## Use i as the index, j as the first argument to precis()
out[[i]] <- precis(j, depth = 2)
}

3. Bonus: It's better to make an empty list of the correct lenght.

So try:

out <- vector("list", length = max_i)

To initialise out before you run the for loop. This makes your code clearer and faster to run.

  • Related