连接路径的功能?

Ada*_*ski 55 r concatenation path

是否存在连接路径的现有功能?

我知道这并不难实现,但仍...除了照顾尾随/(或\)我需要(我们是否写即照顾适当的操作系统路径格式检测C:\dir\file/dir/file).

正如我所说,我相信我知道如何实施它; 问题是:我应该这样做吗?现有R包中是否已存在功能?

Dir*_*tel 97

是, file.path()

R> file.path("usr", "local", "lib")
[1] "usr/local/lib"
R> 
Run Code Online (Sandbox Code Playgroud)

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> 
Run Code Online (Sandbox Code Playgroud)

这将让文件extdata/date_time_zonespec.csv不管

  1. 安装包的地方,和
  2. 操作系统

这非常方便.最后,还有

R> .Platform$file.sep
[1] "/"
R> 
Run Code Online (Sandbox Code Playgroud)

如果你坚持手动做.

  • 很好的答案.但是,该函数不会处理尾随"/",因此`file.path("/ home/user /","project")`会导致无效的`/ home/user // project`.是否有其他功能,或者我应该自己做(尽管如此)? (3认同)
  • 注意`/ home/user // project`和`/ home/user/project`在Unix上都是有效的.你在用什么操作系统? (3认同)
  • 这可能是基本的 R 知识,但如果您已经有 yourlist=list("", "a", "b", "c") 并希望将其转换为路径,`do.call(file.path, yourlist) ` (2认同)

Ada*_*ski 5

如果有人愿意,这是我自己的职责path.cat。它的功能与 Python 的功能相当os.path.join,但有额外的糖分,它解释了...

使用此函数,您可以分层构造路径,但与 不同的是file.path,您可以让用户通过放置绝对路径来覆盖层次结构。作为补充,他可以将“..”放在路径中任何他喜欢的位置,具有明显的含义。

例如

  • path.cat("/home/user1","project/data","../data2")产量/home/user1/project/data2

  • path.cat("/home/user1","project/data","/home/user2/data")产量/home/user2/data

该函数仅适用于斜杠作为路径分隔符,这很好,因为 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]))
}
Run Code Online (Sandbox Code Playgroud)

  • 很酷的评论,但有一个重要的区别:“normalizePath()”要求路径实际存在于 R 服务器上。这可能并不总是理想的。对我来说这是一个重要的区别。OTOH 手册说“normalizePath()”在 Windows 上将短名称转换为长名称。 (2认同)