Se qualcuno lo desidera, questa è la mia funzione path.cat
. La sua funzionalità è paragonabile a quella di Python os.path.join
con lo zucchero extra, che interpreta lo ..
.
Con questa funzione, è possibile costruire i percorsi gerarchicamente, ma a differenza dello file.path
, si lascia all'utente la possibilità di sovrascrivere la gerarchia impostando un percorso assoluto. E come aggiunta di zucchero, può mettere il ".." ovunque nel percorso, con ovvio significato.
ad es.
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 funzione funziona solo con barre come separatore di percorso, che va bene, poiché R li traduce trasparente a barre rovesciate sulla macchina 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]))
}
fonte
2014-01-23 16:00:18
Ottima risposta. Ma la funzione non si occupa del trailing "/", quindi 'file.path ("/home/user/"," project ")' produce un progetto '/ home/utente // non valido '. C'è un'altra funzione, o dovrei farlo da solo (banalmente, però)? –
Si ottiene se si inizia con una stringa vuota: 'file.path (" "," home "," utente "," progetto ")' produce '"/home/utente/progetto "' –
Si noti che '/ home/utente // project' e '/ home/user/project' sono entrambi validi su Unix. Su quale sistema operativo sei? – flodel