Skip to content

Instantly share code, notes, and snippets.

@joshbode
Created March 11, 2013 05:41
Show Gist options
  • Select an option

  • Save joshbode/5132104 to your computer and use it in GitHub Desktop.

Select an option

Save joshbode/5132104 to your computer and use it in GitHub Desktop.
# Path functions ported to R from Python os.path module
path_join = function(a, ...) {
p = list(...)
path = a
for (b in p) {
b_wins = 0 # set to 1 iff b makes path irrelevant
if (path == "") {
b_wins = 1
}
else if (isabs(b)) {
# This probably wipes out path so far. However, it's more
# complicated if path begins with a drive letter:
# 1. join('c:', '/a') == 'c:/a'
# 2. join('c:/', '/a') == 'c:/a'
# But
# 3. join('c:/a', '/b') == '/b'
# 4. join('c:', 'd:/') = 'd:/'
# 5. join('c:/', 'd:/') = 'd:/'
if (substring(path, 2, 2) != ":" || substring(b, 2, 2) == ":") {
# Path doesn't start with a drive letter, or cases 4 and 5.
b_wins = 1
}
# Else path has a drive letter, and b doesn't but is absolute.
else if (nchar(path) > 3 || (nchar(path) == 3 && substring(path, nchar(path)) %nin% c('/', '\\'))) {
# case 3
b_wins = 1
}
}
if (b_wins) {
path = b
}
else {
# Join, and ensure there's a separator.
if (substring(path, nchar(path)) %in% c('/', '\\')) {
if (b != '' && substring(b, 1, 1) %in% c('/', '\\')) {
path = paste(path, substring(b, 2), sep='')
}
else {
path = paste(path, b, sep='')
}
}
else if (substring(path, nchar(path)) == ":") {
path = paste(path, b, sep='')
}
else if (b != '') {
if (substring(b, 1, 1) %in% c('/', '\\')) {
path = paste(path, b, sep='')
}
else {
path = paste(path, '\\', b, sep='')
}
}
else {
# path is not empty and does not end with a backslash,
# but b is empty; since, e.g., split('a/') produces
# ('a', ''), it's best if join() adds a backslash in
# this case.
path = paste(path, '\\', sep='')
}
}
}
return(path)
}
isabs = function(s) {
s = splitdrive(s)[2]
return(s != '' && substring(s, 1, 1) %in% c('/', '\\'))
}
splitdrive = function(p) {
if (substring(p, 2, 2) == ':') {
return(c(substring(p, 1, 2), substring(p, 3)))
}
return(c('', p))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment