Что не так с этой функцией R, выводящей область каждой фигуры?

#r #function

#r #функция

Вопрос:

 area<-function(...){
 x<-c(...)
 cat("It is area of: ", x[1])
 if (x[1]=="triangle"|1) {
   cat("the baseline is: ", x[2])
   cat("the height is: ", x[3])
   cat("Area equals to ",(x[2]*x[3])/2)
 } 
 if (x[1]=="square"|2) {
   cat("the baseline is ", x[2])
   cat("the height is: ", x[3])
   cat("the area is ",x[2]*x[3])
 }
}

area(1,4,2)
 

Что не так с этой функцией? Я пытаюсь создать здесь функцию, которая должна отображать результат областей для треугольников, квадратов в R. Пожалуйста, помогите мне с ошибками.

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

1. Синтаксис (x[1]=="triangle"|1) неправильный. Вы могли бы сделать (x[1] == "triangle" | x[1] == 1)

2. Спасибо за любезный комментарий, но у x<-c(…) нет проблем? Консоль продолжает выводить, что она неожиданная.

3. Джулия, если вы используете выражение x <- c(...) в интерактивном режиме (в консоли), вы получите сообщение об ошибке ( Error: '...' used in an incorrect context ), но оно отлично работает в вашей функции. Многоточие ... является специальным и определяется только в области видимости в теле функции, которая имеет ... в качестве аргумента. Когда вы отправляете отдельную строку в REPL, это не так.

Ответ №1:

Здесь можно было бы улучшить несколько вещей. Основная проблема заключается в том, что ваш синтаксис неверен; вы не можете сделать if(x[1] == "square"|2) . Вам нужно будет сделать что-то вроде if(x[1] == "square" | x[1] == 2) . Однако даже это проблематично. Если ваш первый аргумент является строкой (например, если вы вызвали area("triangle", 2, 3) , то c(...) строка преобразует 3 записи в символьный вектор, поэтому математические операции не будут работать.

У вас также есть ненужные повторения в вашем коде, которые могут быть источником ошибок.

Наконец, ваши cat вызовы не имеют разрывов строк, что делает вывод беспорядочным.

Объединив эти изменения, вот воспроизводимый пример того, как может работать функция:

 area <- function(...){
 x <- c(...)
 area <- x[2] * x[3]
 if (x[1] == 1)  area <- area / 2
 cat("It is area of:", c("triangle", "square")[x[1]])
 cat("nThe baseline is:", x[2])
 cat("nThe height is:", x[3])
 cat("nArea equals to", area)
}

area(1, 4, 2)
#> It is area of: triangle
#> The baseline is: 4
#> The height is: 2
#> Area equals to 4
 

Лучшим, более идиоматичным способом сделать это было бы использовать именованные параметры вместо c(...) . Это значительно упрощает сохранение правильных типов. Например, следующая функция намного проще для чтения и понимания и позволяет передавать числа или строки в качестве первого аргумента:

 area <- function(shape, base, height){
 if(is.numeric(shape)) shape <- c("triangle", "square")[shape]
 area <- base * height
 if (shape == "triangle")  area <- area / 2
 cat("It is area of:", shape)
 cat("nThe baseline is:", base)
 cat("nThe height is:", height)
 cat("nArea equals to", area)
}

area(1, 4, 2)
#> It is area of: triangle
#> The baseline is: 4
#> The height is: 2
#> Area equals to 4

area("triangle", 4, 2)
#> It is area of: triangle
#> The baseline is: 4
#> The height is: 2
#> Area equals to 4
 

Создано 2020-12-13 пакетом reprex (версия 0.3.0)

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

1. Спасибо! Однако в этом случае я также должен получить площадь треугольника, даже когда я выполняю вычисление по площади (‘triangle’, 4, 2). Так что, невозможно сделать функцию таким образом?

2. @JuliaKim это не невозможно. Смотрите мое обновление

3. Спасибо за обновления, это мне очень помогло. На самом деле, мне любопытно, могу ли я расширить эту функцию, чтобы получить области кругов и трапеций, которые имеют разное количество аргументов.

4. @JuliaKim да, вы можете это сделать. Какие аргументы вы бы хотели, чтобы эти фигуры имели?

5. Это очень похоже. Итак, для случая кругов area (circle, 3) должна показывать результат 3 ^ 2 * pi, в то время как area (трапеция, 2,3,4) должна показывать ((2 3)*4)/2