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