Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
RCoreTeam2014.docx
Скачиваний:
46
Добавлен:
08.10.2015
Размер:
539.13 Кб
Скачать
    1. Область действия

Обсуждение в этом разделе является несколько более схематичным, чем в других частях этого документа. Однако детализируется одно из существенных различий между 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)

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]