Search code examples
rexportnaming

How to name files with correct alphanumerical syntax in R?


I am trying to save a list of pngs of my plots, and I want the plots to be correctly alphanumerically ordered when named. Meaning, I do not want a plot named 10Plot.png to be found earlier than one named 1Plot.png. Since I am using Image Magick to make gifs from the plots, this order is important, and I would need the numbering to be three digits at all times. So, I need 1Plot.png to actually be 001Plot.png, 10Plot.png to be 010Plot.png, and so on.

Below is a minimal example just focusing on how I am currently naming the pngs:

plotCount <- 100 # How many plots I would like to create a name for

nameList <- list() # Empty list to just contain the names

for(i in 1:plotCount){
  nameList[i] <- paste(i, "_Plot.png", sep = "")
}

I am using the nameList to simply represent what I need (correctly named pngs), to avoid requiring someone to make 100 pngs on their computer.


Solution

  • R is vectorized, you don't need loops.

    plotCount <- 100L
    
    nameList <- sprintf("%03d_Plot.png", seq.int(plotCount))
    head(nameList, 20)
    #>  [1] "001_Plot.png" "002_Plot.png" "003_Plot.png" "004_Plot.png" "005_Plot.png"
    #>  [6] "006_Plot.png" "007_Plot.png" "008_Plot.png" "009_Plot.png" "010_Plot.png"
    #> [11] "011_Plot.png" "012_Plot.png" "013_Plot.png" "014_Plot.png" "015_Plot.png"
    #> [16] "016_Plot.png" "017_Plot.png" "018_Plot.png" "019_Plot.png" "020_Plot.png"
    

    Created on 2023-03-08 with reprex v2.0.2


    Edit

    And here is a for loop solution, as requested in comment. Also with sprintf.

    plotCount <- 100L # How many plots I would like to create a name for
    nameList <- character(plotCount) # Empty vector to just contain the names
    
    for(i in seq.int(plotCount)){
      nameList[i] <- sprintf("%03d_Plot.png", i)
    }
    
    head(nameList, 20)
    #>  [1] "001_Plot.png" "002_Plot.png" "003_Plot.png" "004_Plot.png" "005_Plot.png"
    #>  [6] "006_Plot.png" "007_Plot.png" "008_Plot.png" "009_Plot.png" "010_Plot.png"
    #> [11] "011_Plot.png" "012_Plot.png" "013_Plot.png" "014_Plot.png" "015_Plot.png"
    #> [16] "016_Plot.png" "017_Plot.png" "018_Plot.png" "019_Plot.png" "020_Plot.png"
    

    Created on 2023-03-08 with reprex v2.0.2


    Edit 2

    If all that is needed is a new, consecutively numbered name, then the following might be better.

    Note that I have changed plotCount to only 10L, a test doesn't need to print 100 lines.

    plotCount <- 10L # How many plots I would like to create a name for
    
    for(i in seq.int(plotCount)){
      png_name <- sprintf("%03d_Plot.png", i)
      # do something with this string, 
      # here I print it
      cat("This is the current PNG name:", png_name, "\n")
    }
    #> This is the current PNG name: 001_Plot.png 
    #> This is the current PNG name: 002_Plot.png 
    #> This is the current PNG name: 003_Plot.png 
    #> This is the current PNG name: 004_Plot.png 
    #> This is the current PNG name: 005_Plot.png 
    #> This is the current PNG name: 006_Plot.png 
    #> This is the current PNG name: 007_Plot.png 
    #> This is the current PNG name: 008_Plot.png 
    #> This is the current PNG name: 009_Plot.png 
    #> This is the current PNG name: 010_Plot.png
    

    Created on 2023-03-08 with reprex v2.0.2