Is there an existing function to concatenate paths?
I know it is not that difficult to implement, but still... besides taking care of trailing /
(or \
) I would need to take care of proper OS path format detection (i.e. whether we write C:\dir\file
or /dir/file
).
As I said, I believe I know how to implement it; the question is: should I do it? Does the functionality already exist in existing R package?
path. join() method in Python join one or more path components intelligently. This method concatenates various path components with exactly one directory separator ('/') following each non-empty part except the last path component.
Combines an array of strings into a path. Combine(String, String) Combines two strings into a path.
Yes, file.path()
R> file.path("usr", "local", "lib") [1] "usr/local/lib" R>
There is also the equally useful system.path()
for files in a package:
R> system.file("extdata", "date_time_zonespec.csv", package="RcppBDT") [1] "/usr/local/lib/R/site-library/RcppBDT/extdata/date_time_zonespec.csv" R>
which will get the file extdata/date_time_zonespec.csv
irrespective of
which is very handy. Lastly, there is also
R> .Platform$file.sep [1] "/" R>
if you insist on doing it manually.
In case anyone wants, this is my own function path.cat
. Its functionality is comparable with Python's os.path.join
with the extra sugar, that it interprets the ..
.
With this function, you can construct paths hierarchically, but unlike the file.path
, you leave the user the ability to override the hierarchy by putting an absolute path. And as an added sugar, he can put the ".." wherever he likes in the path, with obvious meaning.
e.g.
path.cat("/home/user1","project/data","../data2")
yelds /home/user1/project/data2
path.cat("/home/user1","project/data","/home/user2/data")
yelds /home/user2/data
The function works only with slashes as path separator, which is fine, since R transparently translates them to backslashes on Windows machine.
library("iterators") # After writing this function I've learned, that iterators are very inefficient in R. library("itertools") #High-level function that inteligentely concatenates paths given in arguments #The user interface is the same as for file.path, with the exception that it understands the path ".." #and it can identify relative and absolute paths. #Absolute paths starts comply with "^\/" or "^\d:\/" regexp. #The concatenation starts from the last absolute path in arguments, or the first, if no absolute paths are given. path.cat<-function(...) { elems<-list(...) elems<-as.character(elems) elems<-elems[elems!='' && !is.null(elems)] relems<-rev(elems) starts<-grep('^[/\\]',relems)[1] if (!is.na(starts) && !is.null(starts)) { relems<-relems[1:starts] } starts<-grep(':',relems,fixed=TRUE) if (length(starts)==0){ starts=length(elems)-length(relems)+1 }else{ starts=length(elems)-starts[[1]]+1} elems<-elems[starts:length(elems)] path<-do.call(file.path,as.list(elems)) elems<-strsplit(path,'[/\\]',FALSE)[[1]] it<-ihasNext(iter(elems)) out<-rep(NA,length(elems)) i<-1 while(hasNext(it)) { item<-nextElem(it) if(item=='..') { i<-i-1 } else if (item=='' & i!=1) { #nothing } else { out[i]<-item i<-i+1 } } do.call(file.path,as.list(out[1:i-1])) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With