Skip to content

Constant index incorrectly flagged as dynamic index when name begins with . #1621

Description

@kenkellner

On CRAN nimble 1.4.2.

If you provide an index in constants and its name starts with a period, you will get an error or extra warning note (depending on if indexing another constant or a parameter, respectively) which incorrectly flags the index as dynamic when running nimbleModel.

I think I've narrowed down the issue to the creation of constantsNamesList, here:

constantsNamesList <<- lapply(ls(constants), as.name)

By default ls omits object names that start with a period, according to the docs. So constants starting with a . don't show up in this list, and later checks against constantsNamesList incorrectly determine that they are not constants.

You can set the argument all.names = TRUE in ls to include them. You also have to set the same argument in as.list here:

constantsEnvCopy <- list2env(as.list(constantsEnv))

I'm not sure what kind of side effects this might have. I can make a PR with these changes if needed.

Reproducible example:

library(nimble)

# note index is named 'site'
constants <- list(n = 4, x = rnorm(2), site = c(1,1,2,2))
data <- list(y = rnorm(4))

code <- nimbleCode({
  for (i in 1:n){
    mu[i] <- beta0 + beta1 * x[site[i]]
    y[i] ~ dnorm(mu[i], sd = 1)
  }
})

# works fine
mod <- nimbleModel(code, constants=constants, data=data) 

# now rename index to .site
constants <- list(n = 4, x = rnorm(2), .site = c(1,1,2,2))
data <- list(y = rnorm(4))

code <- nimbleCode({
  for (i in 1:n){
    mu[i] <- beta0 + beta1 * x[.site[i]]
    y[i] ~ dnorm(mu[i], sd = 1)
  }
})

# errors
mod <- nimbleModel(code, constants=constants, data=data)

# Also issues when indexing a non-constant
# back to 'site'
constants <- list(n = 4, site = c(1,1,2,2))
data <- list(y = rnorm(4))

code <- nimbleCode({
  for (i in 1:n){
    y[i] ~ dnorm(mu[site[i]], sd = 1)
  }
  mu[1] ~ dnorm(0, sd = 1)
  mu[2] ~ dnorm(0, sd = 1)
})

# works
mod <- nimbleModel(code, constants=constants, data=data)
mod$modelDef$constantsNamesList # site is here

# now switch to .site
constants <- list(n = 4, .site = c(1,1,2,2))
data <- list(y = rnorm(4))


code <- nimbleCode({
  for (i in 1:n){
    y[i] ~ dnorm(mu[.site[i]], sd = 1)
  }
  mu[1] ~ dnorm(0, sd = 1)
  mu[2] ~ dnorm(0, sd = 1)
})

# gives apparently incorrect warning note about
# non-constant indexes
mod <- nimbleModel(code, constants=constants, data=data)
mod$modelDef$constantsNamesList # .site is not included
mod$modelDef$constantsList # it's here though

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions