2012-02-03 62 views
4

是否有任何R用戶知道R中的「打開文件」類型函數? 優選地,它就會有一個文本界面,例如:R命令行文件對話框?類似於file.choose

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

而且我可以通過瀏覽,直到我選擇我想要的文件(S)。

上午意識到目前file.choose,但(在Linux反正),只是說:「中輸入文件名:」並採取任何你輸入,但不給你瀏覽的能力。 (也許在Windows上顯示「打開文件」對話框?)。

我喜歡打開文件對話框,但寧願遠離加載GUI包,如RGtk2/tcltk /等只是爲此。

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

歡呼聲。

更新

答案對於基於文本的界面是「否」。但基於@ 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) 
} 

這可能與符號鏈接和BARF的 '..',因爲我用normalizePath,..但很好哦。

+0

在Windows和Mac上,它確實提供了您詢問的GUI類型瀏覽器。我記得第一次在Linux上使用file.choose ...我認爲這是無用的,並希望某種瀏覽器! – Dason 2012-02-03 02:01:24

+0

我個人不介意file.choose,但是我將這段代碼給了一些合作者,他們輸入的路徑很容易出現拼寫錯誤,所以我只想要一些只會讓他們選擇現有文件的東西。 – 2012-02-03 02:03:09

+0

結合shell.exec(我大部分時間都是windows用戶;所以不知道其他操作系統上的等效命令是什麼),這非常好。感謝分享數學咖啡。'shell.exec(my.file.browse())'或'shell.exec(my.file.browse(根= path.expand( 「〜」)))' – 2012-02-03 19:37:52

回答

2

我有種你想做的,我保留在我的.R檔案中。它有一個菜單界面,因爲它是默認的查看工作目錄。如果你想把它擴展到從根目錄開始,並從那裏找出菜單,你必須做很多修改功能。

該函數僅在菜單中找到.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") 
+0

歡呼聲 - 我正在考慮寫一個類似的功能,但我會等待看看有沒有人知道 - 這將是一個遞歸的痛苦編程(探索子文件夾等)。好的片段! – 2012-02-03 02:03:42

+1

@ mathematical.coffee也許我是昏昏沉沉的,但我不太明白你的意思是遞歸是必要的。正如我所看到的那樣,你有一個狀態,並期望一個選擇,它打開一個編輯器,或一個while循環,它只是更新一個狀態(即目錄和列表),直到做出選擇或退出。 – Iterator 2012-02-03 02:28:38

+0

@Iterator哦。這是完全正確的。 D'哦! :P – 2012-02-03 04:18:04

1

這不使用「菜單」,但我希望能夠顯示「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() 

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

+0

謝謝@Dason!我最終爲這個函數寫了自己的函數,它和你的函數幾乎完全一樣:PI只是使用'menu'來完成選擇部分,所以我不必自己驗證數字輸入(我做了「修改並將D添加到字符串的開頭「)。對不起,我不能選擇這兩個作爲答案,但非常感謝你:) – 2012-02-03 05:20:22

+0

@ mathematical.coffee不用擔心!我很開心寫它。我在提交它之後立即編輯了一些內容,並意識到您已經編寫了自己的函數。你的介紹看起來比我的更好,泰勒給了你一個開始,所以我明白了!當我嘗試了你的函數時,多重選項讓我循環了一秒,因爲當我最終選擇一個文件時,我認爲我做了錯誤。這是一個有趣的想法,但允許選擇多個文件。你認爲默認值應該是多個= T?在我看來,更多的時候我們只想選擇一個文件。 – Dason 2012-02-03 05:28:30

+0

是的,默認值應該是multiple = F--這就是我需要選擇多個文件的項目之一。 – 2012-02-03 06:00:10

相關問題