rloopscbind

How to cbind multiple dataframes for a particular year and write them as .csv in a loop in R


I have a list of dataframes for years 2025 to 2050. These are for 3 variables: temperature, precpitation and RH. I want to combine (cbind) all 3 variables for each year, rename their columns and then save as csv. E.g.

> combined_2025<-cbind(tasmean_2025,prmean_2025,rhmean_2025)
> colnames(combined_2025) <- c("tasmean","pr","rh")
> write.csv(combined_2025,"D:/...../combined_annual_mean_245_2025.csv")

Now, I can easily do this for one year, but I have 25 years to work on. I was thinking of a for loop, but that isn't working for cbind. Please suggest a more efficient way.


Solution

  • 1) We need a reproducible example to really know what you have and to test the code but here is some code that you can fix/modify accordingly. I tested it by replacing the first two lines (defining years and fmt) with years <- 2025; tasmean_2025 <- pr_2025 <- rh_2025 <- 1:3; fmt <- "combined_%d.csv" .

    years <- 2025:2050
    fmt <- "D:/combined_annual_mean_245_%d.csv"  # change this
    Names <- c("tasmean", "pr", "rh")
    
    
    for (y in years) {
      Names_ <- paste0(Names, "_", y)
      # DF <- do.call("data.frame", L[Names_])  # if data is in list L
      DF <- do.call("cbind", mget(Names_))  # if data is loose in workspace
      names(DF) <- Names
      file <- sprintf(fmt, y)
      cat("writing", file, "\n")
      write.csv(DF, file)
    }
    

    2) Another possibility if you would like to consider other ways of storing the result is to combine everything into a single data frame with an added year column and then write that out as a single csv.

    library(dplyr)
    library(purrr)
    
    years <- 2025:2050
    Names <- c("tasmean", "pr", "rh")
    
    make_df <- function(year) {
      Names_ <- paste0(Names, "_", y)
      # DF <- do.call("data.frame", L[Names_])  # if data is in list L
      DF <- do.call("data.frame", mget(Names_, .GlobalEnv))  # if data is loose in workspace
      names(DF) <- Names
      DF
    }
    
    DF <- map(years, make_df) %>% set_names(years) %>% bind_rows(.id = "year")
    write.csv(DF, "combined.csv")
    

    If at some later time we wanted to split it up we could still do that using R or we could use the command line miller utility which is available on all platforms that support R.

    mlr --csv --from combined.csv split -g year