vendredi 27 mars 2020

Save every nth file to a new subfolder following a if statement in R

first of all, apologies if this question has already been addressed somewhere else but I couldn't find an answer.

In R I have a for loop that saves text (writeLines) to a file according to a certain condition. Every 10th written file I would like to save to a new different subfolder. In this way each subfolder will only have a maximum of 10 files.

Now, I can code a script that does that if all files were to be written (see below), but I'm not sure how to implement the change of subfolder every time a folder is full with 10 files.

The example below should clarify.

# generate random num
set.seed(15)
input <- rnorm(100, mean = 10, sd = 3)
# Write to file only if num is greater than threshold
thrshld <- 10
out_dir <- "~/R/tmp/Batch_Saving"

k <- 1
i <- 1
for (i in 1:length(input)) {

  if ( any(i == seq(from = 1, to = length(input), by = 10) ) ) {

    # Create a new subfolder everytime i is a multiple of 10
    sub_dir <- paste0(out_dir, "/Dir_Num_", k) 
    k <- k+1

  } 

  if ( input[i] > thrshld) {

    txt <- paste("The number", signif(input[i], 4), "is greater than", thrshld)

    # Create folder if it doesn't exist
    if (!dir.exists(sub_dir)) { dir.create(sub_dir, recursive = T) }

    # Write text to file
    writeLines(text = txt,
               con = paste0(sub_dir, "/file_", i, ".txt") )

  }

}

This script creates 10 folders where each as less than 10 files, but not the same number of files. One can check this quickly in the terminal like this:

Batch_Saving > find . -maxdepth 1 -mindepth 1 -type d -exec sh -c 'echo "{} : $(find "{}" -type f | wc -l)" file\(s\)' \;

./Dir_Num_4 :        6 file(s)
./Dir_Num_3 :        7 file(s)
./Dir_Num_2 :        4 file(s)
./Dir_Num_5 :        7 file(s)
./Dir_Num_10 :        4 file(s)
./Dir_Num_9 :        5 file(s)
./Dir_Num_7 :        3 file(s)
./Dir_Num_6 :        6 file(s)
./Dir_Num_1 :        6 file(s)
./Dir_Num_8 :        4 file(s)

I believe the only way to achieve this is to either read every time how many files have been written already or to somehow keep tracks of how many files have already been written and change accordingly the parameter k.

I believe this could also be achieved with other methods (i.e. apply) but for sake of learning I'd like to code this in a loop.

Thanks a lot!

Aucun commentaire:

Enregistrer un commentaire