2012-02-03 1 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: 

이있을 것이다 그리고 난 내가 원하는 파일을 선택할 때까지를 통해 검색 할 수있을 것입니다.

I 현재 file.choose 알고 있지만, 단지 말한다 (어쨌든 리눅스) 오전 "파일 이름을 입력 :"당신이 입력 어떤 필요하지만 당신이 검색 할 수있는 기능을 제공하지 않습니다. (아마도 Windows에서는 "파일 열기"대화 상자가 나타납니다).

나는 열린 파일 대화 상자를 사용하기 쉽지만 RGtk2/tcltk/etc와 같은 GUI 패키지를로드하는 것을 선호합니다.

나는 또한 위의 텍스트 브라우저를 직접 작성할 수는 있지만 휠을 다시 만들려고 시도하기 전에 누군가가 그런 기능을 알고 있는지 물어볼 것입니다. (작동하기 전에 여러 번 잘못 입력하십시오.)

건배.

업데이트

답변은 텍스트 기반 인터페이스에서 "아니오"입니다. 그러나 @Iterator에 의해 @의 TylerRinker의 솔루션과 의견에 따라, 나는 그것을 할 내 자신의 기능을 썼다 (그리고 내가 그들 덕분에 생각했던 것보다 훨씬 쉽게했다!) :

편집-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을 사용하기 때문에 ..하지만 오 잘.

+0

Windows 및 Mac에서는 사용자가 묻는 GUI 유형 브라우저를 제공합니다. 나는 리눅스에서 file.choose를 처음 사용하는 것을 기억한다 ... 나는 쓸모가 없다고 생각하고 어떤 종류의 브라우저를 원했다! – Dason

+0

필자는 개인적으로 file.choose를 신경 쓸 필요는 없지만 일부 공동 작업자에게이 코드를 제공하고 있습니다. 입력하는 경로에 따라 오타가 생기기 쉽기 때문에 기존 파일을 선택할 수있는 무언가가 필요했습니다. . –

+0

shell.exec와 결합하면 (나는 대부분 윈도우 사용자이기 때문에 다른 OS에 상응하는 명령이 무엇인지 잘 모름) 이것은 꽤 좋다. 수학 커피를 공유해 주셔서 감사합니다.'shell.exec (my.file.browse())'또는'shell.exec (my.file.browse (root = path.expand ("~")))' –

답변

2

나는 내 .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") 
+0

환호 - 나는 비슷한 기능을 쓰려고했다. 누군가가 이미 알고 있는지 알기 위해 기다릴 것입니다 - 그것은 재귀적인 것 (하위 폴더를 탐색하는 것 등)에서 통증 프로그래밍이 될 것입니다. 멋진 발췌 문장! –

+1

@ mathematical.coffee 어쩌면 나는 덩치가 크지 만 재귀에 관해서는 무슨 뜻인지 알기가 어렵습니다. 보시다시피, 상태가 있고 편집기를 여는 선택 영역 또는 선택 또는 종료가 이루어질 때까지 상태 (즉, 디렉토리 및 목록)를 업데이트하는 while 루프가 필요합니다. – Iterator

+0

@Iterator Oh. 맞습니다. D' oh! : P –

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를 추가하십시오 "). 죄송합니다 나는이 두 가지를 답으로 선택할 수는 없지만 대단히 감사합니다. –

+0

@ mathematical.coffee 걱정하지 마십시오! 나는 그것을 쓰는 재미를 가지고 있었다. 내가 그것을 제출하고 당신이 당신 자신의 기능을 썼다는 것을 깨달은 직후에 나는 약간의 것을 편집했다. 당신의 프리젠 테이션은 제 것보다 좋게 보입니다. 그리고 타일러가 당신에게 시작을주었습니다. 그래서 나는 이해합니다! 내가 마지막으로 파일을 선택했을 때 뭔가 잘못된 생각을했기 때문에 여러 옵션을 사용하여 잠시 동안 루프를 던져 버렸습니다. 하나 이상의 파일 선택을 허용하는 것은 흥미로운 아이디어입니다. 디폴트가 multiple = T가되어야한다고 생각합니까? 더 자주 우리는 하나의 파일 만 선택하기를 원합니다. – Dason

+0

네, 기본값은 아마도 multiple = F 여야합니다. 단지이 함수의 필요성이 항상 여러 파일을 선택해야하는 프로젝트 중 하나에서 발생했기 때문입니다. –