Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function to concatenate paths?

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?

like image 959
Adam Ryczkowski Avatar asked Oct 28 '12 15:10

Adam Ryczkowski


People also ask

How do you concatenate paths in Python?

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.

What is path combine?

Combines an array of strings into a path. Combine(String, String) Combines two strings into a path.


2 Answers

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

  1. where the package is installed, and
  2. the OS

which is very handy. Lastly, there is also

R> .Platform$file.sep [1] "/" R>  

if you insist on doing it manually.

like image 98
Dirk Eddelbuettel Avatar answered Sep 29 '22 03:09

Dirk Eddelbuettel


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])) } 
like image 32
Adam Ryczkowski Avatar answered Sep 29 '22 04:09

Adam Ryczkowski