omirz
omirz

Reputation: 37

Function for looping over common variable names with different suffixes in R

I have some code which I'm looking to replicate many times, each for a different country as the suffix.

Assuming 3 countries as a simple example:

country_list <- c('ALB', 'ARE', 'ARG') 

I'm trying to create a series of variables called a_m5_ALB, a_m5_ARE, a_m5_ARG etc which have various functions e.g. addcol or round_df applied to reg_math_ALB, reg_math_ARE, reg_math_ARG etc

for (i in country_list) {
 
  paste("a_m5", i , sep = "_")  <- addcol(paste("reg_math", i , sep = "_"))

}

for (i in country_list) {
 
  paste("a_m5", i , sep = "_")  <- round_df(paste("reg_math", i , sep = "_"))

}


where addcol and round_df are defined as:

addcol = function(y){
    dat1 = mutate(y, p.value = ((1 - pt(q = abs(reg.t.value), df = dof))*2))
    return(dat1)
}

round_df <- function(x, digits) {
    numeric_columns <- sapply(x, mode) == 'numeric'
    x[numeric_columns] <-  round(x[numeric_columns], digits)
    x
}

The loop errors when any of the functions are added in brackets before the paste variable part but it works if doing it manually e.g.

a_m5_ALB <- addcol(reg_math_ALB)

Please could you help? I think it's the application of the function in a loop which i'm getting wrong.

Errors:

Error in UseMethod("mutate_") : 
  no applicable method for 'mutate_' applied to an object of class "character"

Error in round(x[numeric_columns], digits) : 
  non-numeric argument to mathematical function

Thank you

Upvotes: 1

Views: 290

Answers (1)

Alexlok
Alexlok

Reputation: 3134

From your examples, you're really in a case where everything should be in a single dataframe. Here, keeping separate variables for each country is not the right tool for the job. Say you have your per-country dataframes saved as csv, you can rewrite everything as:

library(tidyverse)
country_list <- c('ALB', 'ARE', 'ARG') 

read_data <- function(ctry){
  read_csv(paste0("/path/to/file/", "reg_math_", ctry)) %>%
  add_column(country = ctry)
}

total_df <- map_dfr(country_list, read_data)

total_df %>%
  mutate(p.value = (1 - pt(q = abs(reg.t.value), df = dof))*2) %>%
  mutate(across(where(is.numeric), round, digits = digits))

And it gives you immediate access to all other dplyr functions that are great for this kind of manipulation.

Upvotes: 1

Related Questions