#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