Reputation: 6278
Let's say I have two files in different directories:
Scripts/Script.R
.Templates/Template.docx
If these paths are both relative to the same directory, then the path of the second file relative to the first is "../Templates/Template.docx
".
Using R, how can I construct relative filepaths like this in an automated way (i.e. using a function)?
Ideally, I'm hoping there's a function that looks something like the following:
> rel_path(path = 'Templates/Template.docx',
rel_to = 'Scripts/Script.R')
[1] "../Templates/Template.docx"
Upvotes: 2
Views: 225
Reputation: 144
Here is a function I wrote that does that. You need to specify the directory (main_dir
) that contains both files.
rel_path <- function(target_file, ref_file, main_dir){
## Returns the path of a file relative to a given path within a given directory.
# Args:
# target_file: name of the file for which the relative path is to be returned.
# ref_file: name of the reference file.
# main_dir: path of the directory that encompases both the target and the reference files.
#
# Returns:
# String with the relative file path.
#
target_path <- list.files(path = main_dir,
pattern = target_file,
recursive = TRUE)
ref_path <- list.files(path = main_dir,
pattern = ref_file,
recursive = TRUE)
## Split paths into strings to check if they have common sub directories
ref_str <- (strsplit(ref_path,"/|\\\\")[[1]])
tar_str <- (strsplit(target_path,"/|\\\\")[[1]])
## compare
max_len <- min(length(tar_str), length(ref_str))
matched <- which(ref_str[1:max_len] == tar_str[1:max_len])
if (length(matched)==0){
matched = 0
}
if (length(ref_str) == 1){ ## The reference file is not inside a sub directory
rel_path = file.path(target_path)
}else if (length(matched) == length(tar_str) && length(tar_str) == length(ref_str) ){
rel_path = file.path(target_file)
}else if (max(matched) == 1){ ## Both files are under same sub directory
rel_path = file.path(target_path)
}else if (sum(matched) == 0){
count_up <- paste0(rep("..", length(ref_str)-1), collapse = "/")
rel_path = file.path(count_up, target_path)
}else{ ## files under different sub directory
count_up <- paste0(rep("..", max(matched)-1), collapse = "/")
rel_path = paste0(c(count_up,
paste0(tar_str[3:length(tar_str)], collapse = "/")),
collapse = "/")
}
return(rel_path)
}
This should then work provided that both are under the directory folder1
.
> rel_path(target_file= 'Template.docx',
ref_file = 'Script.R', main_dir = 'folder1')
[1] "../Templates/Template.docx"
Upvotes: 2