R пропущенные аргументы во входных данных функции, не соответствующие имени

#r #function #arguments #missing-data

#r #функция #аргументы #отсутствуют-данные

Вопрос:

У меня есть функция, подобная

 dbh2vol <- function(dbh,hgt,...){

  if (missing(hgt)){
    hgt = 2
    cat("hgt is missing. Set to 2")
  }
  vol  = dbh * hgt
  return(vol)
}
  

если я затем вызову его с помощью

 Vol = dbh2vol(dbh=10,hgt=4)
#40
  

все в порядке. Если у меня есть что-то вроде

 Vol = dbh2vol(dbh=10,param=4)
#hgt is missing. Set to 2[1] 20
  

как и ожидалось. Но если тогда я

 Vol = dbh2vol(dbh=10,h=4)
#40
  

h=4 интерпретируется как hgt=4 . Почему и как я могу избежать такого поведения, то есть как аргументы могут быть точно сопоставлены по их именам?

Комментарии:

1. Я не смог воспроизвести это… Для тестирования я просто установил hgt=2*dbh вместо hgt = some_other_function(dbh) then ran Vol = dbh2vol(dbh=10,param=4) . Результат Vol , который я получил , был 200 таким , как и следовало ожидать , если бы я установил hgt = 2*dbh .

2. Я попытался воспроизвести минимальный пример, который я предоставил. На самом деле есть очень странная вещь. Делая Vol = dbh2vol(dbh=10,param=4) это, я также получаю правильный результат. Если я изменю на Vol = dbh2vol(dbh=10,h=4) then h , который на самом деле является тем, что у меня есть в моем коде, распознается так, как если бы это было hgt . Можете ли вы проверить это поведение.

3. Для меня это похоже на ошибку. Такое же поведение, если я использую hg . Похоже, что если имя аргумента соответствует хотя бы начальной части ожидаемого ввода, оно не задается как missing

Ответ №1:

то, что вы наблюдаете, — это частичное совпадение аргументов именованной функции, и, насколько я знаю, вы не можете его отключить. см. Определение языка r для получения дополнительной информации https://cran.r-project.org/doc/manuals/R-lang.html#Argument-matching

может быть, вы можете поместить аргумент hgt в три точки и проверить это? конечно, тогда вы теряете позиционное соответствие.

 dbh2vol <- function(dbh, ...){
  hgt <- list(...)$hgt
  if (is.null(hgt)) {
    hgt <-  sqrt(dbh)
    cat("hgt has been calculated with some_other_function")
  }
  vol = dbh * hgt
  return(vol)
}
  

Комментарии:

1. Спасибо. Я попробую с вашим решением, по крайней мере, я знаю причину такого странного поведения.

2. Или просто поместите hgt after ... в список аргументов.

Ответ №2:

Вместо передачи dbh и hgt в качестве аргумента, вы можете попробовать это:

 pars <- list(
    dbh = 10,
    h = 5
)

dbh2vol <- function(pars){
  with(pars,{
    if (!exists("hgt")){
        hgt <- 2
        cat("hgt is missing. Set to 2")
    }
    vol <- dbh * hgt
    return(vol)  
  })
}

dbh2vol(pars)
## hgt is missing. Set to 2[1] 20
  

Это позволяет вам легко передавать параметры и другим функциям.