Search code examples
robjectfunctional-programmingsubsetassign

How to assign a name to an object by pasting


Consider the data frame dat:

dat <- data.frame(Loc = c("NY","MA"),
                  ID = c(1:2),
                  Sex = c("M","F")
                  )

Pretending there were a lot more data to go with this, and multiple observations for each ID, I want to fit a model and save it in an object called NYM1mod, which to me would stand for "model for New York Male number 1" I can use: paste(dat[1,1], dat[1,3], dat[1,2],"mod", sep="") to output what I want: [1] "NYM1mod" But how can I do something like this and make the output the name of a new object? For example, why can you not assign the number 3 to the output "NYM1mod" like this?: paste(dat[1,1], dat[1,3], dat[1,2],"mod", sep="") <- 3


Solution

  • As commented, consider using a list instead of many separate objects. Specifically, generalize your modeling process in a defined function. Iterate it with lapply to return a list of objects. Then rename with setNames to return a single, named list of objects, indexable for all. some, or one item without flooding global environment with many, separate objects:

    proc_model <- function(...) {
        # MODELING PROCESS 
        ...
        return(model)
    }
    
    model_list <- setNames(lapply(sequence_pass_as_params, proc_model),
                           paste0(dat$Loc, dat$Sex, dat$ID, "mod"))
    
    # ALL MODELS
    model_list 
    
    # SELECT MODELS
    model_list$NYM1mod    
    model_list$MAF2mod
    

    In fact, if I understand your needs consider by (another sibling to apply family as object-oriented wrapper to tapply) to pass subset data frames of Loc, ID, and Sex into your modeling function. Wrap process with tryCatch for subsets that do not exist and/or yields modeling errors.

    # RECEIVE DATA FRAME AS PARAMETER
    proc_model <- function(df) {
        tryCatch({
            # MODELING PROCESS 
            model <- lm(..., data = df)
            }, error = function(e) return(NULL)
        )
    }
    
    # BUILD MODEL LIST BY SUBSETS
    model_list <- by(dat, dat[,c("Loc", "Sex", "ID"), proc_model)
    
    # RENAME ELEMENTS IN LIST WITH UNIQUE NAMES
    model_list <- setNames(model_list, unique(paste0(dat$Loc, dat$Sex, dat$ID, "mod")))
    
    # REMOVE EMPTY MODELS  (I.E., ITEMS THAT RETURN NULL)
    model_list <- Filter(model_list, LENGTH)
    
    # ALL MODELS
    model_list 
    
    # SELECT MODELS
    model_list$NYM1mod    
    model_list$MAF2mod