- •Написание собственных функций
- •Простые примеры
- •Определение новых бинарных операторов
- •Именованные параметры и умолчания
- •Параметр ‘...’
- •Присвоения в пределах функций
- •Более сложные примеры
- •Фактор эффективности при проектировании блоков
- •Отбрасывание всех имен при печатании массива
- •Рекурсивное числовое интегрирование
- •Область действия
- •Настройка окружения
- •Классы, универсальные функции и объектно-ориентированное программирование
- •Статистические модели в r
- •Определение статистических моделей; формулы
- •Примеры
- •Противопоставления
- •Линейные модели
- •Универсальные функции для извлечения информации о модели
- •Дисперсионный анализ и сравнение модели
- •Таблицы anova
- •Обновление подогнанных моделей
- •Обобщенные линейные модели
- •Семейства
- •Функция glm()
- •Нелинейные наименьшие квадраты и модели наибольшего правдоподобия
- •Наименьшие квадраты
- •Метод максимального правдоподобия
- •Некоторые нестандартные модели
Область действия
Обсуждение в этом разделе является несколько более схематичным, чем в других частях этого документа. Однако детализируется одно из существенных различий между S-Plus и R .
Символы в теле функции могут быть разделены на три класса: формальные параметры, локальные переменные и свободные переменные. Формальные параметры функции это те, которые возникли в списке параметров функции. Их значение определяется процессом связывания фактических аргументов функции с формальными аргументами. Локальные переменные это те, значение которых определено оценкой выражений в теле функций. Переменные, которые не являются формальными параметрами или локальными переменными, называют свободными переменными. Свободные переменные становятся локальными переменными, если им они присваиваются. Рассмотрим следующее определение функции.
f <- function(x) { y <- 2*x print(x) print(y) print(z) }
В этой функции x - формальный параметр, y - локальная переменная и z - свободная переменная.
В R связывание свободной переменной разрешается сначала путем поиска в области, в которой создавалась функция. Это называют лексическим контекстом. Сначала определим функцию cube. cube <- function(n) { sq <- function() n*n n*sq()
}
Переменная n в функции sq не является аргументом этой функции. Поэтому - это свободная переменная, и следует использовать правила области действия, чтобы установить значение, которое должно быть ей назначено. Согласно статической области действия (S-Plus) значение определяется глобальной переменной с именем n. В области действия (R) она является параметром функции cube, так как это активное связывание переменной n в момент определения функция sq. Разность между оценкой в R и оценкой в S-Plus в том, что S-Plus ищет глобальную переменную с именем n, а R сначала ищет переменную с именем n в окружении, созданном после определения cube.
## сначала вычислим в S
S> cube(2)
Error in sq(): Object "n" not found
Dumped
S> n <- 3
S> cube(2)
[1] 18
## затем та же функция, вычисленная в R
R > cube(2)
[1] 8
Также лексический контекст может использоваться для изменения состояния функциям. В следующем примере покажем, как можно использовать R для имитации банковского счета. У функционирующего банковского счета должны быть баланс или итог, функция для вывода средств, функция для формирования депозитов и функция определения текущего баланса. Это достигается путем создания трех функций в внутри счета (account), а затем возвращения списка, содержащего их. Когда счет (account) заводится, то он принимает числовой аргумент total и возвращает список, содержащий три функции. Поскольку эти функции определены в среде, которая содержит total, у них будет доступ к ее значению.
Специальный оператор присваивания `<<-` используется для изменения значения, связанного с total. Этот оператор делает обратный проход в окружающие среды, которые содержит символ total, и когда он находит такую среду, то заменяет значение в той среде значением с правой стороны. Если среда глобального или верхнего уровня достигнута, не находя символа total, то создается переменная и там присваивается. Для большинства пользователей <<- создает глобальную переменную и присваивает ей значение правой стороны. Лишь когда <<- использовался в функции, которая вернула в качестве значения другой функции, то возникает специальный режим, описанный здесь.
open.account <- function(total) {
list(
deposit = function(amount) { if(amount <= 0) stop("Deposits must be positive!\n") total <<- total + amount
cat(amount, "deposited. Your balance is", total, "\n\n")
},
withdraw = function(amount) { if(amount > total) stop("You don’t have that much money!\n") total <<- total - amount
cat(amount, "withdrawn. Your balance is", total, "\n\n")
},
balance = function() { cat("Your balance is", total, "\n\n") }
)
}
ross <- open.account(100)
robert <- open.account(200)
ross$withdraw(30) ross$balance()
robert$balance()
ross$deposit(50) ross$balance() ross$withdraw(500)