【问题标题】:How to get the directory of the executing script in R? [duplicate]如何获取R中执行脚本的目录? [复制]
【发布时间】:2018-08-18 04:46:03
【问题描述】:

我有一个看起来像这样的函数:

read_data <- function(filename, header) {
  path <- paste("./output/", filename, sep = "")
  if (file.exists(path)) {
      data <- read.csv(file = path, header = header, sep = ",")
  }
  # Partially removed for brevity.
}

我想要实现的是,给定一个文件名,我想搜索该文件名在output 子目录中是否可用,该子目录是我的脚本所在的子目录,如果可用,我想读取该文件。问题是只要我知道read.csv 函数的文件参数需要文件的完整路径。所以,我需要以某种方式获取我的脚本所在的目录,这样我就可以将它与其余的子目录和文件名连接起来。我可以使用getwd() 获取当前工作目录,但这并不完全相同,因为我的工作目录似乎总是固定的,而脚本可以位于计算机的任何位置。任何想法如何获取脚本的目录,并将其与输出子目录和 R 中提供的文件名连接起来?

【问题讨论】:

  • 查看list.files() 我认为这可能会解决您的问题。
  • file.exists 函数告诉您文件是否存在。
  • file.exist 在路径上可能无法为您提供所需的内容。您可以在我在下面给您的 list.files 示例周围添加一个 file.exists 包装器,但读取所有内容可能更容易,空格对应于文件名元素编号。
  • 我不清楚您要做什么。你想知道一个文件的完整路径,只知道它的基本名称吗?
  • @nicola 假设这个脚本名为myscript.R,它位于C:\User\myUser\Desktop\myscript.R,并假设R 默认将C:\User\myUser 作为当前工作目录。所以,我想做的是在这个myscript.R里面我想要一些代码来获取它在硬盘中的完整路径,在这个例子中是C:\User\myUser\Desktop\myscript.R

标签: r


【解决方案1】:

如果你想确定执行脚本的目录,这可能是一个 dup:Rscript: Determine path of the executing script

initial.options <- commandArgs(trailingOnly = FALSE)
file.arg.name <- "--file="
script.name <- sub(file.arg.name, "", initial.options[grep(file.arg.name, initial.options)])
script.dirname <- dirname(script.name)
print(script.dirname)

【讨论】:

  • 谢谢乔尔格。
  • 所以它是重复的。
【解决方案2】:
> f <- "/path/to/my/script.R"

> f
[1] "/path/to/my/script.R"

> basename(f)
[1] "script.R"

> dirname(f)
[1] "/path/to/my"

> dirname(dirname(f))
[1] "/path/to"

> file.path(dirname(f), "output")
[1] "/path/to/my/output"

> file.path(dirname(f), "output", "data.csv")
[1] "/path/to/my/output/data.csv"

【讨论】:

  • 没有。您可以考虑向我们展示您尝试运行的命令或描述您的工作环境。例如,您是否在 shell 中执行Rscript myscript.R?您在交互式 R 会话中吗?也许您会对“here”包感兴趣? github.com/krlmlr/here
【解决方案3】:

将此添加为您 Tinker 的答案。

考虑到你只是想读入一个文件,你可以这样做:

## So what does this do?
# The path is where the files exist
# The pattern is some identifiable portion of the file name, which list.files() will bring back
# You need the full name so that R knows where to read from, this way you don't have to set a new working directory.


data <- if(file.exists(list.files(path = "./output/", pattern = "filename",full.names=T))){ read.csv(list.files(path = "./output/", pattern = "filename",full.names=T))}

# Let's imagine you have a number of files to read in

# Generate a list of filenames

filename <- list("file1","file2","file3","filen")

data <- lapply( filename, function(x) {
if( file.exists( list.files( path = "./output/", pattern = x ,full.names=T ) ) ) {
 read.csv( list.files(path = "./output/", pattern = x ,full.names=T) ) }
} )
    # each element of the list is oe of your data files
    data[[1]]
    data[[2]]
    data[[n]]

我不确定你用 header 声明了什么,因为 csv 被假定具有固有的标题,此外 csv 是用逗号分隔的,因此声明 sep 字符也是多余的。

【讨论】:

  • 只有在不声明路径的情况下,如果声明了路径,它会列出该路径中的所有内容。出于这个原因,我不建议使用setwd()。它建立在知道如何调用不在您当前wd 中的东西上的自满情绪。
【解决方案4】:

从 SO 中的多个问题中收集资源,我想出了以下解决方案,它似乎适用于多种调用约定:

library(base)
library(rstudioapi)

get_directory <- function() {
  args <- commandArgs(trailingOnly = FALSE)
  file <- "--file="
  rstudio <- "RStudio"

  match <- grep(rstudio, args)
  if (length(match) > 0) {
    return(dirname(rstudioapi::getSourceEditorContext()$path))
  } else {
    match <- grep(file, args)
    if (length(match) > 0) {
      return(dirname(normalizePath(sub(file, "", args[match]))))
    } else {
      return(dirname(normalizePath(sys.frames()[[1]]$ofile)))
    }
  }
}

以后我可以用作:

path <- paste(get_directory(), "/output/", filename, sep = "")

【讨论】:

    猜你喜欢
    • 2013-07-01
    • 2011-03-23
    • 2023-03-29
    • 2011-12-26
    • 2020-09-06
    • 2012-08-11
    • 2021-05-14
    • 1970-01-01
    • 2017-04-09
    相关资源
    最近更新 更多