Home > Blockchain >  Create a list of function calls in R
Create a list of function calls in R

Time:08-10

I am trying to procedurally create a list of function calls in R.

I am using the depmixS4 package and the mix function. On of the parameters needed for this function is a list of model families (eg. list(multinomial(), multinomial(), gaussian())). In my use case I will be receiving a JSON a list of strings (eg. {'dataFamily': ['categorical', 'categorical', 'continuous']}). I can get the strings into a vector fine, but if I iterate through the strings and add multinomial() or gaussian() to a list it does not add the call, but all of the parameters of the models.

column_data_types <- fromJSON(data_types_JSON)
data_types <- list()
for (col_data_type in column_data_types) {
  if (col_data_type == 'categorical') {
    data_types <- append(data_types, multinomial())
  } else if (col_data_type == 'continuous') {
    data_types <- append(data_types, gaussian())
  }
}

I would expect the length of data_types to be 3, but it is 33:

length(data_types)
[1] 33

Is there any way of programmatically creating the list as expected by depmixS4?

CodePudding user response:

General advice: forget that append exists. It's an utterly ill-named function. It should be called insert, and even then it would be questionable. Just use c here instead. And since you don't want to merge lists (but rather add a single item containing a nested list) you'll have to wrap the second parameter into an additional list call:

data_types <- list()
for (col_data_type in column_data_types) {
  if (col_data_type == 'categorical') {
    data_types <- c(data_types, list(multinomial()))
  } else if (col_data_type == 'continuous') {
    data_types <- c(data_types, list(gaussian()))
  }
}

Or, simpler:

model_types <- list(categorical = multinomial(), continuous = gaussian())
data_types <- model_types[match(column_data_types, names(model_types))]

CodePudding user response:

I think this is to do with your use of append() rather than assigning with [[ notation. This works:

column_data_types <- jsonlite::fromJSON('{"dataFamily": ["categorical", "categorical", "continuous"]}')

data_types <- list()
for (i in seq_along(column_data_types$dataFamily)) {
    col_data_type = column_data_types$dataFamily[i]
  if (col_data_type == 'categorical') {
    data_types[[i]]  <- depmixS4::multinomial()
  } else if (col_data_type == 'continuous') {
    data_types[[i]] <- gaussian()
  }
}


length(data_types) # 3

print(data_types)
# [[1]]

# Family: multinomial
# Link function: mlogit


# [[2]]

# Family: multinomial
# Link function: mlogit


# [[3]]

# Family: gaussian
# Link function: identity
  • Related