0

I have a set of .rmd files that I want to order into a list. I am using the file weight (defined in the files YAML header) to indicate desired position of that file, relative to its neighbors.

Example directory structure:

.
├── dir1
│   ├── dir3
│   │   ├── index.rmd (weight: 1)
│   │   └── file5.rmd (weight: 1)
│   ├── index.rmd (weight: 1)
│   └── file4.rmd (weight: 1)
├── dir2
│   ├── index.rmd (weight: 2)
│   ├── file6.rmd (weight: 1)
│   └── file7.rmd (weight: 2)
├── index.rmd (weight: 1)
├── file2.rmd (weight: 2)
└── file3.rmd (weight: 3)

The goal is to generate a list of files by weight order, starting with . and then iterating through the directories in weight order (as determined by the weight of their index and the weight of their parent). E.g. For the above directory, the order would be:

./index.rmd
./file2.rmd
./file3.rmd
dir1/index.rmd
dir1/file4.rmd
dir1/dir3/index.rmd
dir1/dir3/file5.rmd
dir2/index.rmd
dir2/file6.rmd
dir2/file7.rmd

I can generate a list of files or directories with list.files(filetree, '[.]Rmd$', ignore.case = TRUE, recursive = TRUE) or unique(dirname(files)) respectively, and can access the weight with yaml_front_matter(filename)$weight but am struggling with the meat of it; in particular how to avoid doing this with repeated nested for loops.

cjdbarlow
  • 17
  • 1
  • 5

2 Answers2

1

It sounds like you probably need to use a recursive function here. Here is one that returns a single data frame with all your relevant file paths and the file weights:

get_file_listing <- function(folder, pattern = "*[.]Rmd$")
{
  subdirs <- list.dirs(folder, recursive = FALSE, full.names = FALSE)
  result  <- list.files(folder, full.names = TRUE, pattern = pattern)
  weights <- sapply(result, function(x) yaml_front_matter(x)$weight)
  new_rows <- data.frame(file = result, weights, stringsAsFactors = FALSE)

  for(i in subdirs) {
    new_path <- paste0(folder, "/", i)
    new_rows <- rbind(new_rows, get_file_listing(new_path, pattern))
  }
  new_rows
}
Allan Cameron
  • 56,042
  • 3
  • 16
  • 39
0

but am struggling with the meat of it; in particular how to avoid doing this with repeated nested for loops.

Use one one of the functions from the apply family. That way, you avoid the for loops. I'm sorry, but I can't help you more because you did not post the code you have so far.

That said, I would make a data frame, where each column is a variable I want to sort. And then, I would use the sort or order function. See here for how the sort function works. this also avoids for loops.

MacOS
  • 1,040
  • 1
  • 4
  • 12