Задание произвольных пользовательских функций

Обобщим создание математических функций на случай нескольких значений самой функции.

Задание 4. Запрограммировать функциюPower(x), возвращающую одновременно квадрат и куб своего аргумента .

Решение. Введемна новых строчках следующий код:

Power<- function(x) {# Объявление имени функции Power

P2 <- x^2 # Вычисление квадрата в переменной P2

P3 <- x^3 # Вычисление куба в переменной P3

return(c(P2,P3)) # Возврат значений P2 и P3

}

Power(5) # Вызов функции Power для x =5

Обратим внимание на то, что теперь фигурные скобки {…} после команды function(x) содержат не одно выражение, которое и считалось ранее по умолчанию значением нашей функции, а несколько команд. Во второй строчке мы вычисляем квадрат аргумента и записываем результат в переменную P2, а в третьей строке вычисляем куб и записываем в переменную P3. Следующей строкой мы должны указать компиляторуR какое из вычисленных чисел мы хотим вернуть в качестве результата действия функцииPower(x).

Здесь мы могли бы написать return(P2), и тогда функция вернула бы значение квадрата. Для случая return(P3) получили бы на выходе значение куба. Однако мы остановились на return(c(P2,P3)), иэто означает, что будут выведены оба значения, т.к. результатом выполнения функции будет формирование массива из двух чисел: c(P2,P3). Замечание: вообще, оператор c(x,y,z,…) объединяет свои аргументы в вектор (массив), но об этом позднее.

В итоге после отработки набранного кода, действительно, получаем строку с квадратом и кубом для :

Если бы мы присвоили значение данной функции какой-нибудь переменной, то эта переменная представляла бы собой обычный массив из двух значений. Например,

Z <- Power(11) # Вызов функции Power для x = 11 с сохранением в Z

Z # Посмотреть Z (вывести на экран)

Z[1] # Посмотреть Z[1]

Z[2] # Посмотреть Z[2]

 

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

Задание 5. Запрограммировать в R функцию, отвечающую на вопрос: будет ли спрос (Q) эластичным относительно цены предложения (P) для функции .Здесь под спросом Q мы понимаем долю желающих приобрести товар по цене P.

Решение. Фактически нам необходимо вычислить предельную эластичность функции по переменной по формуле

и выяснить превышает ли ее модуль единицу (случай эластичного спроса) или нет:

.

 

В нашем случае

.

Запишем следующий код в R:

Elasticity<- function(P) { # ОбъявлениеименифункцииElasticity

Q<- 1/(1+P^2) # Вычисление спроса Q по цене P

D <- -2*P/(1+P^2)^2 # Вычисление производной Q по цене P

E <- D*P/Q # Вычисление эластичности E

if (abs(E)>1) {Elasticity<- "Спрос эластичный"} # Проверка условия эластичности

else{ Elasticity<- "Спрос неэластичный"} # Проверка условия неэластичности

return(Elasticity) # Возвращение итогового значения

}

Elasticity(2) #Вызовфункции Elasticity дляцены P=2

Elasticity(0.5) #Вызовфункции Elasticity дляцены P=0.5

Здесь использован условный операторifelse.В синтаксисе языка R он имеет представление:

if (A) {…} else {…}

ЕслиусловиеA выполняется производится группа операторов из первых скобок{…}, иначе – из последних. Важно: Если бы мы хотели записать условие «равно», то использовали бы форму if (abs(E)==1)…, а если бы хотели «не равно», то – if (abs(E)!=1)…

Обратите внимание, что значением нашей функции в данном примере является строка, а не число.

 

Замечание для отличников

Мы могли бы вывести в нашей функции все параметры, связанные с эластичностью: и функцию спроса, и значение ее эластичности, и словесный вывод об эластичности спроса. Делается это все той же командой return, но в качестве аргумента указываетсяобъект специального типа list (список). Все, что мы хотим – это объединить результаты вычислений в один объект, назовем его «Result»:

Result <- list(Price=P, Function=Q, Elastic=E, Answer=Elasticity) # ОбъединениевResult

Здесь команда list объединитв одном объекте все что нам надо. Не забудем вставить этот код в строчку нашей функцииперед командой returnи исправить аргумент вывода Resultв команде return:

return(Result) # Возвращение итогового значенияResult

Если теперь перезапустить все тело функции, то на выходе уже получим полный отчет об исследовании эластичности. (Кстати, если вообще не вводить команду return, то наша функция фактически превратится в процедуру, выполняющую ряд действий, но не возвращающую ничего в качестве объектов. Если же при этом мы совершали какие-либо вычисления, то в качестве возвращаемого значения будет определено последнее).

Обратите внимание, что в результате наша функция возвращает объект, имеющий в своем составе 4 компоненты: Price (цена), Function (спрос), Elastic (эластичность) и Answer (ответ будет ли спрос эластичным). Это означает, что если присвоить какой-либо переменной значение нашей функции для конкретной цены, скажем, переменной Today:

Today<- Elasticity(2) # Запись в переменную Today значенияElasticity(2)

то в переменной Today будут по отдельности доступны следующие части (их называют полями):

Today$Price # Вывести на экран поле Price переменной Today(цена)

Today$Function # Вывести на экран поле Function переменной Today (спрос)

Today$Elastic # Вывести на экран полеElastic переменной Today(эластичность)

Today$Price# Вывести на экран поле Price переменной Today(словесный ответ)

Можно представлять их себе как отдельные самостоятельные переменные, «зашитые» в объекте Today. Мы сталкивались с подобной семантикой в переменной cars, которая содержала в себе по сути два одномерных массива: cars$speed и cars$dist, которые являлись скоростями и длинами тормозных путей. Интересно, что сам языкR понимает переменную carsпо типу и как таблицу (тип data.frame), и каксписок (тип list), и как двумерный массив чисел (тип vector).


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: