Search code examples
rcsvfor-loopassignsubstr

R - Add Column w/ File Name on For Loop


I use assing in a for loop to batch read in all the .csv files in a working directory. I then use substr to clean the names of the files. I would like to add a column to each of the files with the file name for better analysis later in the code. However, I am having trouble referencing the file in the for loopafter the file names have been cleaned to add a column.

#read in all files in folder
files <- list.files(pattern = "*.csv")
for (i in 1:length(files)){
  assign(substr(files[i], start = 11, stop = nchar(files[i])-4),  #clean file names
         read.csv(files[i], stringsAsFactors = FALSE))
  substr(files[i], start = 11, stop = nchar(files[i])-4)['FileFrom'] <- files[i]
}

Solution

  • assign does not seem to be the right function here, I think you need to use eval(parse()) on a string cmd that you set up. The inline notes explain more:

    # read in all files in folder
    files <- list.files(pattern = "*.csv")
    
    # loop through the files
    for (i in 1:length(files)){
      # save the clean filename as a char var because it will be called again
      fnClean = substr(files[i], start = 1, stop = nchar(files[i])-4)
    
      # create a cmd as a string to be parsed and evaluated on-the-fly
      # the point here is that you can use the 'fnClean' var in the string
      # without knowing what it is - assign is expecting an inline string
      # ...not a string saved as a var, so it can't be used in this case
      loadFileCMD = paste0(fnClean,' = read.csv(files[i], stringsAsFactors = 
        FALSE)')
      print(loadFileCMD) # check the cmd
      eval(parse(text=loadFileCMD))
    
      # create another string command to be evaluated to insert the file name
      # to the 'FileFrom' field
      addFnCMD = paste0(fnClean,'$FileFrom = files[i]')
      print(addFnCMD) # check the cmd
      eval(parse(text=addFnCMD))
    }