簡體   English   中英

R命令行文件對話框? 類似於file.choose

[英]R command-line file dialog? similar to file.choose

是否有R用戶知道R中的“打開文件”類型的功能? 優選地,它具有文本界面,例如:

> 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: 

我可以瀏覽直到我選擇我想要的文件。

知道目前的file.choose ,但(在Linux反正),只是說:“中輸入文件名:”並采取任何你輸入,但不給你瀏覽的能力。 (也許在Windows上它顯示一個“打開文件”對話框?)。

我很適合打開文件對話框,但是我更喜歡為此加載像RGtk2 / tcltk / etc這樣的GUI包。

我也可以自己編寫上面的文本瀏覽器,但我想在我嘗試重新發明輪子之前,我會問是否有人知道這樣的功能(並且在它工作之前很多很多次都弄錯了!)

干杯。

更新

對於基於文本的界面,答案是“不”。 但基於@ TylerRinker的解決方案和@Iterator的評論,我編寫了自己的功能來做到這一點(這比我想象的要容易得多!):

編輯 - 修改默認為multiple=F因為通常人們希望選擇一個文件。

#' 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)
}

因為我使用了normalizePath ,它可能會用符號鏈接和'..'進行normalizePath ,但是很好。

我有一些你想要的東西,我保留在我的.Rprofile中。 它有一個菜單界面,因為它是查看工作目錄的默認設置。 如果你想將它擴展為從根目錄開始並使用那里的菜單,你必須做很多修改功能。

該函數僅在菜單中找到.txt .R和.Rnw文件。

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")

這不使用'menu'但我希望能夠顯示“D”,如果某個東西是目錄。 它可以通過在字符串的開頭添加“D”或者其他東西來修改哦。 默認為從當前工作目錄開始。 有很多可以調整和更強大,但這肯定是一個開始。

## 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's 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()

編輯:我沒有看到您的更新。 你的功能比我的好多了! 你應該發布你的答案並接受它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM