Search code examples
rfor-loopdirectorycopystringr

file.copy: Trying to copy a batch of images into a different folder


I am currently trying to write a code that will read through a list of files, confirm it is an image, and then copy this file into its proper IMG folder. The setup of the directories currently has the images in a folder by month, and within this directory are the loose images, along with 4 other folders that were setup using the structureFolder function from phenopix.

I am using a for loop currently, and checking (using the stringr package) if the image's name contains '.jpg', and if True I want this file copied into the IMG folder created using the structureFolder package, which is (what I assume) a shortcut for the folder path for that specific directory. I am not sure what I am doing wrong, but I know that the if statement is working properly as I have tested it out use simple print statements, it's just the file.copy that is not being read properly. Any help is greatly appreciated!

# here is what I have currently
wd <- "~/Desktop/codes/phenocam/DSM/2023/02"
> wd <- "~/Desktop/codes/phenocam/DSM/2023/02"

files <- list.files(wd)
print(files)
> files <- list.files(wd)
> print(files)
   [1] "2023-02-01_10_30_00.jpg" "2023-02-01_11_00_00.jpg"
   [3] "2023-02-01_11_30_00.jpg" "2023-02-01_12_00_00.jpg"
   [5] "2023-02-01_12_30_00.jpg" "2023-02-01_13_00_00.jpg"
# ommitted the majority of file names since it is repetitive

my_path = structureFolder(wd, showWarnings = F)
> my_path = structureFolder(wd, showWarnings = F)
Put all your images in ~/Desktop/codes/phenocam/DSM/2023/02/IMG/ 
Put your reference image in ~/Desktop/codes/phenocam/DSM/2023/02/REF/ 
Draw your ROI with DrawROI():
 set path_img_ref to  ~/Desktop/codes/phenocam/DSM/2023/02/REF/ 
 set path_ROIs to ~/Desktop/codes/phenocam/DSM/2023/02/ROI/ 
Then you can extractVIs(): 
 set img.path as ~/Desktop/codes/phenocam/DSM/2023/02/IMG/ 
 set roi.path as ~/Desktop/codes/phenocam/DSM/2023/02/ROI/ 
 set vi.path to ~/Desktop/codes/phenocam/DSM/2023/02/VI/ 
------------------------
Alternatively, assign this function to an object and use named elements of the returned list

for (file in files) {
  if (stringr::str_detect(file, '.jpg')) {
    file.copy(from = wd, to = my_path$img)
  }
}

After the for loop there is no output, and checking the IMG folder shows that no images have been copied over. Again, any help is greatly appreciated (and also any advice to make it a bit simpler since I am a new(ish) coder! Thanks :)


Solution

  • welcome. Please work to provide reproducible examples, as that is helpful to anyone wanting to help you.

    I expect I didn't get this perfect, but you should be able to build from here using this example.

    # Create list of files and path, include recursive = TRUE only if you want to search sub-directories; use "pattern" to filter to only image files
    my_files <- as_tibble(list.files(recursive = TRUE, full.names = TRUE, pattern = "jpg")) %>%
    # this column brings in only the file name (assuming no sub-folders)
      cbind(as_tibble(list.files(recursive = TRUE, full.names = FALSE, pattern = "jpg")))
    
    # rename columns
    colnames(my_files) <- c("full_path_name", "file_name")
     
    # create lists of each name
    my_files_full_path_name <- unlist(my_files$full_path_name)
    my_files_short_name <- unlist(my_files$file_name)
    
    # copy jpeg files to my IMG file
    file.copy(from = my_files_full_path_name,
              to   = paste("IMG/",my_files_short_name),
              overwrite = TRUE, recursive = FALSE, copy.mode = TRUE)
    

    Keep in mind, list.files and file.copy are vectorized functions, so you don't need a loop.

    Hope this helps.