是否有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
,所以可能会使用符号链接和'..'进行限制,但是很好。
答案 0 :(得分: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")
答案 1 :(得分:1)
这不使用'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()
编辑:我没有看到您的更新。你的功能比我的好多了!你应该发布你的答案并接受它。