How to specify path for list.files() without using setwd()

I am a pretty competent beginner but can’t resolve the following.

list.files() seems to require setting the working directory using setwd().

I need to list.files() from different locations in the same R session. So I start out defining file paths (path1, path2, path3) to 3 different directory locations - which is how I normally work and it works well except for importing files.

For example, if I run
file_names <- list.files(path = “path1”, pattern = "\\.SCO$”)
then the vector will be empty. But if I first setwd(path1) and run the same line it works as expected.

Problem is that to import files from the other 2 locations, I need to setwd(path2) then run list.files, then setwd(path3) and run list.files.

This does get everything into the global environment the way I need, but seems convoluted. I have reviewed this well written similar issue (list.files() operates on knit directory, not setwd() set via Session menu or console · Issue #3843 · rstudio/rstudio · GitHub) and as per this advice, I do have Knitr Directory set to Document Directory (I work mostly in RNotebook but the problem is the same even if you are working from a script - just omit this note on Knitr)

Why don’t I just put all my files in one directory to satisfy list.files()? Because the data come from a source with extremely limited naming parameters and so I need to do a lot of renaming on import - can’t do it at file save time.

So to reiterate - how do I make list.files() point to a specific directory WITHOUT using setwd()?

1 Like

So the most used method to avoid permanent pathing with setwd is to make use of here which provides a lot of great ways to create relative paths based on folder structures etc from your .proj for instance or other setup. Have a look here: GitHub - jennybc/here_here: I love the here package. Here's why. and here: GitHub - r-lib/here: A simpler way to find your files

Okay that looks pretty great. Can you clarify: in the examples in both links there is something like here("data", "file_i_want.csv") and here("inst", "demo-project", "data", "penguins.csv").

The file name is clear, but what do the preceding elements refer to? The directory that hosts the .csv file (in the first case of "data")? In the second case is the file path: inst>demo-project>data>penguins.csv?

Does this still work well if you are not using RProjects formally but just work from .Rmd and .R?

Hi :slight_smile: Yeah you can set it with something like if you have a .Rmd as your main file (so don't have to use .Rproj but I typically would recommend using it). See here:

here::i_am("README.Rmd")
#> here() starts at /home/kirill/git/R/here
here()
#> [1] "/home/kirill/git/R/here"

So in the case of the below, I have a folder called "one" in my main directory and within it I have a folder called "two" and the file I am referring to is sitting in it called "awesome.text".

here("one", "two", "awesome.txt")
#> [1] "/Users/jenny/rrr/here_here/one/two/awesome.txt"

Let me know if this clarifies it for you!

Almost but I'm trying!

So if I had myfile.csv, in the first example the file path is ...here/data/myfile.csv

And in the second it would be ...here_here/one/two/myfile.csv

Okay so last question: if I am trying to list.files() in the directory data as per example 1, how would you use here() in list.files()?

list.files(path = here("data"), pattern = "\\.SCO$")?

I would use it as you have it. So when looking at the below. I should be in the main location when running here::here() and then within that main location I should have a folder data. Running the below code will access that folder and it will only return files that much your pattern specified in pattern as "\\.SCO$"

list.files(path = here::here("data"), pattern = "\\.SCO$")

Okay thank you very much and I see why here() works best with RProjects since everything set in here() will derive from that original file path.

But I still need to return to my original question about specifying a particular file path in list.files() without having to setwd().

I still need to resolve that issue, as I am frequently drawing from a few sources in the same R session without necessarily being from the same project. Any ideas for that?

So you can specify new paths in list.files() with your here::here:() calls. You just need to start "high" enough to be able to do that essentially.

  • You can use a .RMD as shown above as your location.
  • Remember your setwd() will affect your overall session so set that as fair as possible.
  • With here you can go within folders of folders so if you start high enough C:\ as an example anything is possible (but take caution here).

Aha! I finally get it! Very very much appreciated!

1 Like

Can you clarify how to use here() in a for loop for importing files?

If my file names are in a list file_names as per above, and then import them with a loop like this:
for (i in 1:(length(file_names))){ temp.file <- read_delim(file = file_names[i], "\t") and then a simple naming change my.name <- paste0("c", file_names[i]) assign(paste(my.name), temp.file) }

This loop only looks at the current working directory. Adding in a path to the read_delim does not alter the behaviour where the for loop only looks to the current working directory. So adding in path = here::here() or path = path1 in my defined path method does not work to point to a different directory. If I wanted to point to another directory I would have to setwd() first.

How would I use here() or any other directory specifying method?

I am going to have to ask for a reprex. It is becoming too difficult to work with only half the situation. I suggest looking here (FAQ: How to do a minimal reproducible example ( reprex ) for beginners ) and just opening a new topic.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.