0

I am working with the R programming language.

I found the following related question Stackoverflow (how to delete a file with R?) which shows you how to delete a file having a specific name from the working directory:

#Define the file name that will be deleted
fn <- "foo.txt"

#Check its existence
if (file.exists(fn)) {
    #Delete file if it exists
    file.remove(fn)
}

[1] TRUE

My Question: Is it possible to delete files based on whether the file name contains a specific combination of letters (i.e. LIKE 'fo%' )? This way, all files in the working directory starting with the letters "fo" will be deleted.

What I tried so far:

I thought of a way where I could first create a list of all files in the working directory that I want to delete based on their names:

# create list of all files in working directory 
a = getwd()
path.to.csv <- a
files<-list.files(path.to.csv)
my_list = print(files)  ## list all files in path

#identify files that match the condition
to_be_deleted = my_list[grepl("fo",unlist(my_list))]

Then, I tried to deleted this file using the command used earlier:

if (file.exists(to_be_deleted)) {
    #Delete file if it exists
    file.remove(to_be_deleted)
}

This returned the following message:

[1] TRUE TRUE TRUE TRUE TRUE TRUE
Warning message:
In if (file.exists(to_be_deleted)) { :
  the condition has length > 1 and only the first element will be used

Does anyone know if I have done this correctly? Suppose if there were multiple files in the working directory where the names of these files started with "fo" - would all of these files have been deleted? Or only the first file in this list?

Can someone please show me how to do this correctly?

Thanks!

stats_noob
  • 5,401
  • 4
  • 27
  • 83

1 Answers1

1

file.remove accepts a list of file to delete.

Regarding file.exists, it also accepts a list, but it will return a list of logical values, one for each file. And this won't work with if, which requires only one logical value. However, you don't need to check the existence of files that you get from list.files: they obviously exist.

So, the simplest is to remove the if test and just call file.remove:

files <- list.files(path, pattern = "fo")
to_be_deleted <- grep("fo", files, value = T)
file.remove(to_be_deleted)

Or even simpler:

to_be_deleted <- list.files(path, pattern = "fo")
file.remove(to_be_deleted)

A few notes however:

  • Here you don't know in advance if you have the right to delete these files.
  • You don't know either if the names are indeed files, or directory (or something else). It's tempting to believe that file.exists answer the second question, that is, it might tell you that a name is a real file, but actually it does not: file.exists(path) returns TRUE also when path is a directory. However you can detect directories with dir.exists(path). Depending on your specific case, it may or may not be necessary to check for this (for instance, if you know the pattern passed to grep always filters files, it's ok).
  • @ Jean-Claude Arbaut: Thank you so much for your answer! If you have time, can you please show me how this would look like in its full form? thank you so much! – stats_noob Jan 23 '22 at 18:25
  • @stats555 Done. Is simplified a bit: `grep` can return the list of file names, so you don't have to get logical values and subset from the vector. –  Jan 23 '22 at 18:29
  • `list.files` has a pattern argument that takes regex; you don't need a separate `grep` step – camille Jan 23 '22 at 18:34
  • @camille Good point. I modified the answer accordingly. –  Jan 23 '22 at 18:42