I've had to write some code allowing users to select various files for processing in R.
Since they operate my script through a text console, I thought it'd be easier to provide some way for users to select the files they want processed interactively.
Basically, a file dialogue in R.
Furthermore, I wanted to avoid loading in any extra GUI packages (RGtk2,tcltk,...) to keep the script light-weight.
Bingo! In R there's a command
file.choose that allows a user to pick a file.
In Windows or Mac, it comes up with a file dialog.
However in Linux, it has this unhelpful interface:
> file.choose()
Enter file name:
That's it. It doesn't offer the ability to navigate through folders, you just have to know your entire file path and enter it in. I wanted something a bit more guided.
So, after asking
this question at Stack Overflow, and with the help of the friendly people there, I wrote my own function to browse files:
#' Text-based interactive file selection.
#'@param root the root directory to explore
#' (default current working directory)
#'@param multiple boolean specifying whether to allow
#' multiple files to be selected
#'@return character vector of selected files.
#'@examples
#'fileList <- my.file.browse()
my.file.browse <- function (root=getwd(), multiple=F) {
# .. and list.files(root)
x <- c( dirname(normalizePath(root)), list.files(root,full.names=T) )
isdir <- file.info(x)$isdir
obj <- sort(isdir,index.return=T,decreasing=T)
isdir <- obj$x
x <- x[obj$ix]
lbls <- sprintf('%s%s',basename(x),ifelse(isdir,'/',''))
lbls[1] <- sprintf('../ (%s)', basename(x[1]))
files <- c()
sel = -1
while ( TRUE ) {
sel <- menu(lbls,title=sprintf('Select file(s) (0 to quit) in folder %s:',root))
if (sel == 0 )
break
if (isdir[sel]) {
# directory, browse further
files <- c(files, my.file.browse( x[sel], multiple ))
break
} else {
# file, add to list
files <- c(files,x[sel])
if ( !multiple )
break
# remove selected file from choices
lbls <- lbls[-sel]
x <- x[-sel]
isdir <- isdir[-sel]
}
}
return(files)
}
It basically looks at the directory you specify and allows you to choose folders to explore or select.
You can select multiple files too.
The magic boils down to the
menu, which, given a vector
x, will provide a text interface asking the user to choose on element of
x.
Example use:
> fl <- my.file.browse('path/to/dir',multiple=T)
Select file(s) (0 to quit) in folder path/to/dir:
1: ../ (to)
2: subdir/
3: b.jpg
4: a.txt
Selection: 3
Select file(s) (0 to quit) in folder path/to/dir:
1: ../ (to)
2: subdir/
4: a.txt
Selection: 2
Select file(s) (0 to quit) in folder path/to/dir/subdir:
1: ../ (dir)
2: c.jpg
Selection: 2
Select file(s) (0 to quit) in folder path/to/dir/subdir:
1: ../ (dir)
Selection: 0
>
> fl
[1] "path/to/dir/b.jpg"
[2] "path/to/dir/c.jpg"
Nifty! (of course, it could do with improvements - allow for selecting directories say, or filter files shown).
No comments:
Post a Comment