First let's run this function to create the example folder structure:
c("Level1/Level1A/Level1AA",
"Level1/Level1A/Level1AB",
"Level1/Level1B/Level1BA",
"Level1/Level1B/Level1BB",
"Level2/Level2A/Level2AA",
"Level2/Level2A/Level2AB",
"Level2/Level2B/Level2BA",
"Level2/Level2B/Level2BB") %>%
map(dir.create, recursive = T)
Now let's imagine that this folder structure wasn't created by R but given to us as is.
If I run list.dirs
on the parent folder, I will get:
[1] "." "./Level1" "./Level1/Level1A" "./Level1/Level1A/Level1AA" "./Level1/Level1A/Level1AB"
[6] "./Level1/Level1B" "./Level1/Level1B/Level1BA" "./Level1/Level1B/Level1BB" "./Level2" "./Level2/Level2A"
[11] "./Level2/Level2A/Level2AA" "./Level2/Level2A/Level2AB" "./Level2/Level2B" "./Level2/Level2B/Level2BA" "./Level2/Level2B/Level2BB"
However, instead of this character vector, I wish to get a named nested list like this:
list(Level1 = list(Level1A = list("Level1AA",
"Level1AB"),
Level1B = list("Level1BA",
"Level1BB")),
Level2 = list(Level2A = list("Level2AA",
"Level2AB"),
Level2B = list("Level2BA",
"Level2BB")))
What is the easiest way to achieve this?
CodePudding user response:
You could use recursion in base R as follows:
my_fun <- function(x){
ssplit <- function(x){
if(is.data.frame(x))
if(ncol(x)>1) c(by(x[-1], x[1], ssplit)) else as.list(x[[1]])
else lapply(x, ssplit)
}
x <- grep("/", sub("^\\W ", "", x), value = TRUE)
ssplit(read.table(text = x, sep='/', fill = TRUE, header = FALSE))
}
s <- c("Level1/Level1A/Level1AA", "Level1/Level1A/Level1AB",
"Level1/Level1B/Level1BA", "Level1/Level1B/Level1BB", "Level2/Level2A/Level2AA",
"Level2/Level2A/Level2AB", "Level2/Level2B/Level2BA", "Level2/Level2B/Level2BB")
my_fun(s)
$Level1
$Level1$Level1A
$Level1$Level1A[[1]]
[1] "Level1AA"
$Level1$Level1A[[2]]
[1] "Level1AB"
$Level1$Level1B
$Level1$Level1B[[1]]
[1] "Level1BA"
$Level1$Level1B[[2]]
[1] "Level1BB"
$Level2
$Level2$Level2A
$Level2$Level2A[[1]]
[1] "Level2AA"
$Level2$Level2A[[2]]
[1] "Level2AB"
$Level2$Level2B
$Level2$Level2B[[1]]
[1] "Level2BA"
$Level2$Level2B[[2]]
[1] "Level2BB"