100 votes

Fonction pour concaténer les chemins ?

Existe-t-il une fonction permettant de concaténer des chemins ?

Je sais que ce n'est pas si difficile à mettre en œuvre, mais quand même... en plus de s'occuper des trailing / (o \ ) Je devrais m'occuper de la détection correcte du format du chemin d'accès du système d'exploitation (c'est-à-dire si nous écrivons C:\dir\file o /dir/file ).

Comme je l'ai dit, je pense savoir comment l'implémenter ; la question est : dois-je le faire ? La fonctionnalité existe-t-elle déjà dans un paquet R existant ?

158voto

Dirk Eddelbuettel Points 134700

Sí, file.path()

R> file.path("usr", "local", "lib")
[1] "usr/local/lib"
R> 

Il y a aussi le tout aussi utile system.path() pour les fichiers d'un paquet :

R> system.file("extdata", "date_time_zonespec.csv", package="RcppBDT")
[1] "/usr/local/lib/R/site-library/RcppBDT/extdata/date_time_zonespec.csv"
R> 

qui obtiendra le fichier extdata/date_time_zonespec.csv sans tenir compte de

  1. où le paquet est installé, et
  2. l'OS

ce qui est très pratique. Enfin, il y a aussi

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

si vous insistez pour le faire manuellement.

5voto

Adam Ryczkowski Points 2640

Au cas où quelqu'un le voudrait, voici ma propre fonction path.cat . Sa fonctionnalité est comparable à celle de Python. os.path.join avec le sucre supplémentaire, qu'il interprète le .. .

Avec cette fonction, vous pouvez construire des chemins de manière hiérarchique, mais contrairement à la fonction file.path vous laissez à l'utilisateur la possibilité d'ignorer la hiérarchie en mettant un chemin absolu. Et comme un sucre supplémentaire, il peut mettre le ".." où il veut dans le chemin, avec une signification évidente.

par exemple

  • 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

La fonction ne fonctionne qu'avec des barres obliques comme séparateur de chemin, ce qui est bien, puisque R les traduit de manière transparente en barres obliques inversées sur la machine 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]))
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X