【问题标题】:Optional parameters in R functionR函数中的可选参数
【发布时间】:2018-05-17 21:42:38
【问题描述】:

我正在 R 中编写一个函数,该函数采用 data.frame 一个文件路径,生成一个 csv,该 csv 将作为 data.frame 读入。

我目前有这个:

occInput <- function(fileInput, dfInput = NA) {  
  if (is.na(dfInput)) occ.dat <- read.csv(file = fileInput)
  else occ.dat <- dfInput

  #manipulate the data in occ.dat
}

但是,当我实际将 data.frame 作为 dfInput 参数传入时,它会引发警告:

if (is.na(dfInput)) occ.dat <- read.csv(file = fileInput) else occ.dat <- dfInput 中的警告:条件的长度 > 1 并且只有 将使用第一个元素

虽然这实际上不会对我的代码产生不利影响,但它很丑陋,而且它向我表明,有一种更优雅的方法可以在函数中包含一个/或可选参数。

有什么建议吗?我觉得我忽略了一些明显的东西。

【问题讨论】:

  • 我认为检查is.null(dfInput) 是一个更好的选择。

标签: r function


【解决方案1】:

你不应该信任NA,当参数期望获得data.framelist等值时。is.na将每个元素的NA检查返回到这些数据结构。更好的选择可能是使用NULL 初始化您的参数并使用is.NULL 进行检查。另一种选择是在dfInput 参数上使用missing 函数。你的函数定义可以写成:

occInput <- function(fileInput, dfInput = NULL) {  
  if (is.NULL(dfInput)) occ.dat <- read.csv(file = fileInput)
  else occ.dat <- dfInput

  #manipulate the data in occ.dat
}

#OR you can just use missing function

occInput <- function(fileInput, dfInput) {  
  #Perform missing check
  if (missing(dfInput)) occ.dat <- read.csv(file = fileInput)
  else occ.dat <- dfInput

  #manipulate the data in occ.dat
}

【讨论】:

  • 谢谢,missing() 正是我所需要的。比我尝试做的要少得多......
【解决方案2】:

为什么有两个参数?只要有一个并测试它的数据框架:

occInput <- function(Input) {  
  if (!inherits(Input,"data.frame")){
    # its not a data frame, so treat as a file name...
    Input = read.csv(Input)
  }
  # Now Input is a data frame...
}

适用于数据框、数据表和小标题。

【讨论】:

    【解决方案3】:

    我找到了一种(有点笨拙)的方法:使用if (identical(dfInput, NA)) 而不是if (is.na(dfInput)),它不会引发任何错误,因为它会检查两个参数是否相同而不是等价的。

    但是,它对我来说仍然不是很优雅。如果其他人想要更好地解决这个问题,我会留下未解决的问题。

    【讨论】:

      【解决方案4】:

      if 只检查向量的第一个元素,否则会收到警告。

      检查传递参数的class 更容错:

      occInput <- function(fileInput, dfInput = NA) {  
        if ("data.frame" %in% class(dfInput)) print("dfInput contains a data.frame") # read.csv(file = fileInput)
      }
      
      > occInput("adsf")
      > occInput("adsf", "asdf")
      > occInput("adsf", NULL)
      > occInput("adsf", 1:10)
      > occInput(dfInput = as.data.frame(mtcars))
      [1] "dfInput contains a data.frame"
      

      【讨论】:

        猜你喜欢
        • 2018-06-27
        • 2019-10-02
        • 2019-03-17
        • 2017-05-26
        • 1970-01-01
        • 2015-09-12
        • 2017-11-12
        • 2011-10-09
        • 2013-06-10
        相关资源
        最近更新 更多