Search code examples
rmergegetvectorizationlapply

Implement lapply in conjunction with the get() function to vectorize merge of data tables? R


Question: How to implement the lapply function in conjunction with the get() function to merge a list of data tables?

Objective: For each of the elements in ticker_name, merge the data table called "dt_q_'ticker_name[i]'" and that called "meta_'ticker_name[i]'" by common "id" variable:

ticker_name <- c("CTNP", "PB", "SD", "PC", "PE", "TY", "XD") 
for (i in 1:length(ticker_name)) {

  dt <- get(paste0("dt_q_", ticker_name[i]))
  meta <- get(paste0("meta_", ticker_name[i]))
  dt <- merge(x = dt, y = meta, by= c("id"))
  head(dt)
}

My non-working attempt with lapply:

lapply(
  X = ticker_name,
  FUN = 
    merge(x = get(paste0("dt_q_", ticker_name)),
          y = get(paste0("meta_", ticker_name)), by = c("id")
             ))

The error message:

 Error in match.fun(FUN) : 
 c("'merge(x = get(paste0(\"dt_q_\", ticker_name)),
 y = get(paste0(\"meta_\", ' is not a function,
 character or symbol", "'    ticker_name)), by = c(\"id\"))'
 is not a function, character or symbol")

Solution

  • We can use mget to return all the objects into a list and as the corresponding data.table should be merged, use Map which can have multiple arguments

    Map(merge, mget(paste0("dt_q_", ticker_name)), 
        mget(paste0("meta_", ticker_name)),
            MoreArgs =  list(by = 'id'))
    

    Or using lapply, loop through the 'ticker_name' then paste the corresponding 'prefix' part, get the values of the string objects and merge

    lapply(ticker_name, function(x) merge(get(paste0("dt_q_", x)), 
          get(paste0("meta_", x)), by = 'id'))
    

    NOTE: In the OP's code, after looping through the 'ticker_name' ( or ticker_list - not clear), then it is pasteing the prefix with the whole 'ticker_name' which is not the case if we check the for loop where it is looping through the sequence of 'ticker_name'. We can also loop through the sequence

    lapply(seq_along(ticker_name), function(i) {
      dt <- get(paste0("dt_q_", ticker_name[i]))
      meta <- get(paste0("meta_", ticker_name[i]))
      merge(x = dt, y = meta, by= "id")
    
         })