连接path的函数?
有一个现有的函数来连接path吗?
我知道这不是很难实现,但仍然…除了照顾尾随/
(或\
)我需要照顾适当的操作系统path格式检测(即我们是否写C:\dir\file
或/dir/file
)。
正如我所说,我相信我知道如何执行它; 问题是:我应该这样做吗? 这个function已经存在于现有的R包中吗?
是的, file.path()
R> file.path("usr", "local", "lib") [1] "usr/local/lib" R>
对于包中的文件也有同样有用的system.path()
:
R> system.file("extdata", "date_time_zonespec.csv", package="RcppBDT") [1] "/usr/local/lib/R/site-library/RcppBDT/extdata/date_time_zonespec.csv" R>
这将得到文件extdata/date_time_zonespec.csv
而不pipe
- 包的安装位置,以及
- 操作系统
这非常方便。 最后还有
R> .Platform$file.sep [1] "/" R>
如果你坚持手动做。
如果有人愿意,这是我自己的函数path.cat
。 它的function与Python的os.path.join
与额外的糖相媲美,它解释了..
使用这个函数,你可以分层构buildpath,但是与file.path
不同的file.path
,你可以让用户通过放置绝对path来覆盖层次结构。 作为一个附加的糖,他可以把“..”放在任何他喜欢的path上,具有明显的意义。
例如
-
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
该函数只能用斜线作为path分隔符,这很好,因为R在Windows机器上透明地将它们翻译为反斜杠。
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])) }