Необязательные параметры в функции R - PullRequest
0 голосов
/ 18 мая 2018

Я пишу функцию в R, которая принимает data.frame или путь к файлу, что приводит к 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 и только будет использован первый элемент

Хотя это на самом деле не оказывает негативного влияния на мой код, это уродливо, и оно подсказывает мне, что существует более элегантный способ иметь или / или необязательные аргументы в функции.

Есть предложения? Мне кажется, я упускаю из виду нечто очевидное.

Ответы [ 4 ]

0 голосов
/ 18 мая 2018

Почему есть два аргумента?Просто имейте его и проверьте, работает ли его data-framey:

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...
}

с фреймами данных, таблицами данных и таблицами.

0 голосов
/ 18 мая 2018

Вы не должны доверять NA, когда ожидается, что аргумент получит значение как data.frame, list и т. Д. is.na возвращает проверку NA для каждого элемента в эти структуры данных.Лучшим вариантом может быть инициализация аргумента с помощью NULL и проверка с помощью is.NULL.Другим вариантом может быть использование функции missing для аргумента dfInput.Ваше определение функции может быть записано как:

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
}
0 голосов
/ 18 мая 2018

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"
0 голосов
/ 18 мая 2018

Я нашел один (немного хакерский) способ сделать это: использовать if (identical(dfInput, NA)) вместо if (is.na(dfInput)), который не выдает никаких ошибок, так как он проверяет, являются ли два аргумента идентичными чем эквивалент.

Тем не менее, это все еще не кажется мне очень элегантным. Я оставлю вопрос нерешенным на тот случай, если кто-то другой захочет получить лучший ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...