rpls

How to pass additional function in already constrained do.call function creation?


I have created two reprexes below. The one shows the basic do.call working in the expected way. The second one is not working. I am trying to pass functions as arguments to weights in multi_items but I get the error: Error in as.data.frame.default(x[[i]], optional = TRUE) : cannot coerce class ‘"function"’ to a data.frame

I have tried specifying mode_for_use[[i]]() etc but I am not finding the right way to coherence it. I have tried converting it into string but also not getting a result. How exactly can I pass this into my do.call?

library(seminr)


# Basic idea and working --------------------------------------------------
# Define the vectors of strings for constructing composites
composite_names <- c("V7", "V4", "C8", "C5", "C3", "C2", "C7")
item_names <- list("V7", "V4", "C8", "C5", "C3", "C2", "C7")

# Create a list to store the composite objects
composite_list <- list()

# Iterate over the composite_names vector
for (i in seq_along(composite_names)) {
  # Create the composite object using do.call
  composite_obj <- do.call(composite, c(list(composite_names[i]), single_item(item_names[[i]])))
  
  # Append the composite object to the list
  composite_list[[i]] <- composite_obj
}

# Pass the composite_list to constructs using do.call
new_mm <- do.call(constructs, composite_list)


# More complicated example ------------------------------------------------
library(seminr)

# Define the vectors of strings for constructing composites
composite_names <- c("V7", "V4", "C8", "C5", "C3", "C2", "C7")
item_names <- list("V7", "V4", "C8", "C5", "C3", "C2", "C7")
item_values <- list(1:2, 1:4, 1:3, NULL, 1:2, NULL, 1:2)

mode_for_use <- list(seminr::mode_A,seminr::mode_B,seminr::mode_B,seminr::mode_B,seminr::mode_B,seminr::mode_B,seminr::mode_B)


# Create a list to store the composite objects
composite_list <- list()

# Iterate over the composite_names vector
for (i in seq_along(composite_names)) {
  # Check if item_values[i] is NULL or not
  if (is.null(item_values[[i]])) {
    # If item_values[i] is NULL, create the composite object using single_item
    composite_obj <- do.call(composite, c(list(composite_names[i]), single_item(item_names[[i]])))
  } else {
    # If item_values[i] is not NULL, create the composite object using multi_items
    composite_obj <- do.call(composite, c(list(composite_names[i]), multi_items(item_names[[i]], item_values[[i]], weights = mode_for_use[[i]])))
  }
  
  # Append the composite object to the list
  composite_list[[i]] <- composite_obj
}

# Pass the composite_list to constructs using do.call
new_mm <- do.call(constructs, composite_list)


Solution

  • I believe you need to pass the weights param to the composite() function, not the multiItems() function. A revised version of your second do.call() is as below:

    composite_obj <- do.call(
      what = composite, 
      args = list(
        "construct_name" = composite_names[i],
        "item_names" = multi_items(item_names[[i]], item_values[[i]]),
        "weights" = mode_for_use[[i]]
      )
    )