...">

R command line? similar to file.choose

Do users of R know about the "open file" function in R? Preferably it has a text interface, for example:

> file.choose("/path/to/start/at") path/to/start/at: [1] [D] a_directory [2] [D] another_directory [3] [F] apicture.tif [4] [F] atextfile.txt ... [..] Go up a directory Enter selection: 

And I can browse until I select the files I need.

I am aware of the current file.choose , but (on Linux anyway) that just says β€œenter the file name:” and takes everything that you enter but does not give you the ability to browse. (Perhaps in Windows it shows the "open file" dialog?).

I succumb to an open dialog box, but prefer to stay away from downloading a GUI package such as RGtk2 / tcltk / etc.

I could also write the aforementioned text browser, but I decided that I would ask to see if anyone knew about such a function before I try to invent the wheel (and I’m mistaken many, many, times before it works!)

greetings.

Update

The answer is no for the text interface. But based on @TylerRinker's solution and comments from @Iterator, I wrote my own function to do this (and it was much easier than I thought thanks to them!):

Change - changed by default to multiple=F , as usually people expect to select one file.

 #' 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 could be barf with symbolic links and ".." since I am using normalizePath , .. but ok.

+4
source share
2 answers

I have what you want to do so that I save my .Rprofile. It has a default menu interface for viewing the working directory. If you want it to be expanded to start from the root directory and work with the menu, you will need to change the function a lot.

The function finds only the .txt.R and .Rnw items in the menu.

 Open <- function(method = menu) { wd<-getwd() on.exit(setwd(wd)) x <- dir() x2 <- subset(x, substring(x, nchar(x) - 1, nchar(x)) == ".R" | substring(x, nchar(x) - 3, nchar(x)) %in%c(".txt", ".Rnw")) if (is.numeric(method)) { x4 <- x2[method] x5 <- as.character(x4) file.edit(x5) } else { switch(method, menu = { x3 <- menu(x2) x4 <- x2[x3] x5 <- as.character(x4) file.edit(x5) }, look = file.edit(file.choose())) } } ########## #Examples ######### Open() Open("L") 
+2
source

This does not use a β€œmenu”, but I wanted to be able to display β€œD” if something was a directory. It could probably have been changed just by adding β€œD” to the beginning of the line or something else, but good. This default value starts with the current working directory. There are many possibilities that could be changed and made more reliable, but this is certainly the beginning.

 ## File chooser file.chooser <- function(start = getwd(), all.files = FALSE){ DIRCHAR <- "D" currentdir <- path.expand(start) repeat{ ## Display the current directory and add .. to go up a folder display <- c(dir(currentdir, all.files = all.files)) ## Find which of these are directories dirs <- c(basename(list.dirs(currentdir, rec=F))) if(!all.files){ display <- c("..", display) dirs <- c("..", dirs) } ## Grab where in the vector the directories are dirnumbers <- which(display %in% dirs) n <- length(display) ## Create a matrix to display out <- matrix(c(1:n, rep("", n), display), nrow = n) ## Make the second column an indicator of whether it a directory out[dirnumbers, 2] <- DIRCHAR ## Print - don't use quotes print(out, quote = FALSE) ## Create choice so that it exists outside the repeat choice <- "" repeat{ ## Grab users input ## All of this could be made more robust choice <- scan(what = character(), nmax = 1, quiet = T) ## Q or q will allow you to quit with no input if(tolower(choice) == "q"){ return(NULL) } ## Check if the input is a number k <- suppressWarnings(!is.na(as.numeric(choice))) if(k){ break }else{ ## If the input isn't a number display a message cat("Please input either 'q' or a number\n") } } ## Coerce the input string to numeric choice <- as.numeric(choice) if(out[choice, 2] != DIRCHAR){ ## If the choice isn't a directory return the path to the file return(file.path(currentdir, out[choice, 3])) }else{ ## If the input is a directory add the directory ## to the path and start all over currentdir <- path.expand(file.path(currentdir, out[choice, 3])) } } } file.chooser() 

Edit: I have not seen your update. Your function is pretty nice than mine! You must send your answer as an answer and accept it.

+1
source

Source: https://habr.com/ru/post/1394521/


All Articles