Главная страница

А. Б. Шипунов, Е. М. Балдин, П. А. Волкова, А. И. Коробейников, С. А. Назарова


Скачать 3.04 Mb.
НазваниеА. Б. Шипунов, Е. М. Балдин, П. А. Волкова, А. И. Коробейников, С. А. Назарова
Анкорrbook
Дата29.09.2022
Размер3.04 Mb.
Формат файлаpdf
Имя файлаrbook.pdf
ТипДокументы
#705644
страница18 из 19
1   ...   11   12   13   14   15   16   17   18   19

рассмотрим код вида if (x > 1) y <- -1 else y <- 1
В случае когда x имеет длину 1, получаемый результат вполне соот- ветствует ожиданиям. Однако как только длина x становится больше
1
, все перестает работать. В данном случае код можно векторизовать при помощи функции ifelse():

Правила переписывания. Векторизация
243
ifelse(x > 1, -1, 1)
В общем случае синтаксис функции следующий:
ifelse(cond, vtrue, vfalse)
Результатом функции ifelse() является вектор той же длины, что и вектор-условие cond. Векторы vtrue и vfalse переписываются до этой длины. В вектор результата записывается элемент вектора vtrue в случае, если соответствующий элемент вектора cond равен TRUE, либо элемент вектора vfalse, если элемент cond равен FALSE. В противном случае в результат записывается NA.
Стандартным желанием при выполнении векторизации является ис- пользование функции из apply()-семейства: lapply(), sapply() и т. п.
В большинстве случаев результат получится гораздо хуже, чем если бы векторизации не было вообще (в этом примере мы предварительно явно выделили память под вектор v, чтобы исключить влияние менеджера памяти на результат):
> d <- 1:1000000
> v <- numeric(length(d))
> system.time(for (i in 1:length(d)) v[i] <- pi*d[i]^2/4)
user system elapsed
4.463 0.009 4.504
> system.time(v <- sapply(d, function(d) pi*d^2/4))
user system elapsed
8.062 0.165 8.383
> system.time(v <- pi*d^2/4)
user system elapsed
0.024 0.001 0.024
Такие результаты для времени выполнения вполне объяснимы. Пер- вый фрагмент кода выполняется целиком на интерпретаторе. Послед- ний за счет использования векторизованных операций проводит боль- шую часть времени в ядре среды R (то есть в неинтерпретируемом ко- де). Второй же фрагмент совмещает худшие стороны первого и третьего фрагментов:
• Функция sapply() исполняется в неинтерпретируемом коде.
• Второй аргумент функции sapply() является интерпретируемой функцией.

244
Основы программирования в R
Таким образом, для вычисления одного элемента вектора d необхо- димо запустить интерпретатор для тривиальной функции, выполнить эту функцию и получить результат. Как следствие накладные расхо- ды, необходимые на запуск интерпретатора, доминируют во времени исполнения кода.
Излишняя векторизация может приводить не только к увеличению времени выполнения, но и к существенному расходу памяти. Предполо- жим, что встала задача заменить все отрицательные элементы таблицы данных df на 0. Естественно, это можно сделать в полностью вектори- зованном виде:
df[df < 0] <- 0
Однако, как только таблица данных df станет очень большой, эта конструкция будет требовать памяти в два раза больше, нежели размер таблицы данных, тем самым потенциально приводя к нехватке свобод- ной памяти для среды.
Альтернативой может быть заполнение по строкам:
for (i in nrow(df)) df[i, df[i, ] < 0] <- 0
или же по столбцам:
for (i in ncol(df)) df[df[, i] < 0, i] <- 0
Выбор того или иного варианта зависит от соотношения числа строк и столбцов в таблице данных и от того, что является более важным —
скорость исполнения кода или потребление памяти (хотя как только заканчивается доступная физическая память и начинается использова- ние файла подкачки, ни о какой производительности не может быть и речи).
Наряду с функциями apply()-семейства, существует еще несколько полезных векторизованных функций. Самая интересная из них, навер- ное, функция do.call(), которая вызывает выражение из своего перво- го аргумента для каждого элемента своего второго аргумента-списка.
Это очень удобно, когда нужно преобразовать список в матрицу или таблицу данных, поскольку ни cbind(), ни rbind() не могут обрабаты- вать списки. Вот как это делается:
> (spisok <- strsplit(c("Вот как это делается",
+ "Другое немного похожее предложение"), " "))
[[1]]
[1] "Вот" "как" "это" "делается"

Отладка
245
[[2]]
[1] "Другое" "немного" "похожее" "предложение"
> do.call("cbind", spisok)
[,1]
[,2]
[1,] "Вот"
"Другое"
[2,] "как"
"немного"
[3,] "это"
"похожее"
[4,] "делается" "предложение"
> do.call("rbind", spisok)
[,1]
[,2]
[,3]
[,4]
[1,] "Вот"
"как"
"это"
"делается"
[2,] "Другое" "немного" "похожее" "предложение"
Мы сделали здесь полезную вещь — разобрали две строки текста на слова и разместили их по ячейкам. Это часто требуется при конвер- тации данных. Обратите внимание на первую команду — она выводит свой результат одновременно и на экран, и в объект spisok! Таков эф- фект наружных круглых скобок. Это похоже на то, что делает в UNIX
команда tee.
В.7. Отладка
Возможности отладки кода в среде R достаточно разнообразны. Од- нако они могут показаться несколько непривычными для тех, кто уже пользовался интегрированными средами разработки для других язы- ков. Эти отличия вполне объяснимы: все механизмы отладки должны работать одинаково хорошо как из консольного неитерактивного режи- ма, так и из какой-либо среды-надстройки.
При возникновении ошибки естественно желание (как правило, оно возникает первым) узнать, в какой функции ошибка возникла. Такую возможность предоставляет функция traceback(): она показывает стек вызовов функций до момента возникновения последней ошибки. Отме- тим, что в последних версиях R сообщения об ошибках существенно улучшились, и в большинстве случаев функция traceback() становит- ся ненужной.
foo <- function(x) { print(1); bar(2) }
bar <- function(x) { x + a.variable.which.does.not.exist }
foo(2)
[1] 1
Error in bar(2) : object ’a.variable.which.does.not.exist’
not found

246
Основы программирования в R
traceback()
2: bar(2)
1: foo(2)
Функция browser() позволяет расставить точки остановки: вызов этой функции внутри кода приводит к появлению мини-отладчика (по сути дела — просто к остановке выполнения программы и вызову консо- ли R с окружением текущей функции в качестве основного окружения).
Команды отладчика:
c
(или cont, или просто нажатие клавиши Enter) приводит к выхо- ду из отладчика и продолжению выполнения кода со следующей строки.
n вводит отладчик в режим пошагового просмотра кода. В этом слу- чае смысл команд c и n меняется:
n приводит к выполнению текущей строки и остановке на сле- дующей;
c выполняет код до конца текущего контекста, то есть до за- крывающей фигурной скобки, конца цикла, условного опера- тора, до выхода из функции и т. п.
where выводит стек вызовов функций до текущей.
Q
приводит к завершению работы как отладчика, так и выполняе- мого кода.
Все остальные выражения, набранные в консоли отладчика, интер- претируются как обычные выражения языка R, исполненные в окру- жении вызванной функции: в частности, если набрать имя объекта и нажать Enter, то этот объект будет напечатан; вызов функции ls()
позволяет получить имена всех переменных в окружении вызванной функции (в случае, если потребуется вывести содержимое переменных с именами, совпадающими с именами команд отладчика, это можно сде- лать посредством явного вызова функции print() с соответствующей переменной в качестве аргумента).
Функция recover() обладает схожей функциональностью, но позво- ляет просматривать и отлаживать не только функцию, из которой она была вызвана, но и любую активную в данный момент (то есть любую по стеку вызовов). Впрочем, ее основное предназначение — работа в ка- честве postmortem-отладчика, вызов этой функции можно «повесить»
на всякое возникновение ошибки:

Отладка
247
options(error = recover)
foo <- function(x) { print(1); bar(2) }
bar <- function(x) { x + a.variable.which.does.not.exist }
foo(2)
[1] 1
Error in bar(2) : object ’a.variable.which.does.not.exist’
not found
Enter a frame number, or 0 to exit
1: foo(1)
2: bar(2)
Selection:
Функция debug() позволяет поставить глобальный флаг отладки на функцию: при любом ее вызове произойдет переход в отладочный ре- жим. Команды отладчика те же, что и при вызове функции browser()
в пошаговом режиме. Флаг отладки остается на функции до тех пор,
пока не будет снят при помощи функции undebug().
Функция debugonce() позволяет поставить флаг отладки на функ- цию только на одно выполнение.
foo <- function(x) { print(1); bar(2) }
bar <- function(x) { x + a.variable.which.does.not.exist }
debug(bar)
foo(2)
[1] 1
debugging in: bar(2)
debug: {
x + a.variable.which.does.not.exist
}
Browse[2]>
Функция debug() не требует модификации исходного кода для от- ладки. Аналогичную (только более широкую функциональность) предо- ставляет функция trace(), позволяющая вставить вызовы произволь- ных функций (например, browser() или recover()) в произвольные места других функций. Мы не будем детально останавливаться на всех ее (весьма обширных) возможностях. Рассмотрим только несколько при- меров.
• Вставка вызова произвольного кода при выходе из данной функ- ции осуществляется при помощи аргумента exit (значением ар-

248
Основы программирования в R
гумента может быть произвольное невычисленное выражение, не только имя функции)
foo <- function(x) { print(1); }
trace(foo, exit = browser)
foo(1)
[1] 1
Tracing foo(1) on exit
Called from: eval(expr, envir, enclos)
Browse[1]>
• В сложных случаях можно отредактировать текст функции и вста- вить в нужные места код отладки посредством передачи аргумен- та edit:
foo <- function(x) { print(1); }
trace(foo, edit = TRUE)
Отменить трассировку функции можно вызовом функции untrace().
Интерактивную отладку предоставляет пакет debug. Среди его воз- можностей стоит отметить поддержку множественных окон отладки,
содержащих выполняемый код, возможность назначения точек оста- новки (в том числе по условию) и т. д. Мы не будем останавливаться детально на работе с этим пакетом, всю информацию можно получить из встроенной справки:
install.packages("debug") # Установка пакета debug library(debug)
# Подключение пакета help(package=debug)
# Вызов справки
В.8. Элементы объектно-ориентированного программирования в R
Объектно-ориентированное программирование является простой, но в то же время достаточно мощной идеей, существенно упрощающей ра- боту с похожими сущностями. Язык R предоставляет достаточно бога- тые инструменты для объектно-ориентированного программирования
(ООП). Более того, в рамках языка существуют две различные кон- цепции ООП: версии 3 (S3) и версии 4 (S4). Мы кратко остановимся исключительно на версии S3 и только в объеме, необходимом для по- нимания, «что тут вообще происходит».

Элементы объектно-ориентированного программирования в R
249
ООП в стиле S3 выглядит достаточно просто. Функция может быть универсальной
(generic), то есть производить различные действия в за- висимости от типа переданного аргумента. Универсальные функции связаны с одним или несколькими методами (methods). Метод — это,
собственно, функция, которая вызывается для объекта данного типа.
Таким образом, универсальные функции осуществляют диспетчериза- цию вызова в зависимости от типа переданного объекта на функцию- метод. Типичными примерами таких универсальных функций, с кото- рыми приходится иметь дело постоянно, являются функции print(),
plot()
, summary().
За «объектно-ориентированность» отвечает атрибут class, являю- щийся просто текстовым вектором. Этот вектор просматривается слева направо, при этом ищется функция-метод, отвечающая данному «клас- су». Если таковая функция найдена, то она вызывается. В противном случае (если просмотрен весь вектор class) вызывается метод по умол- чанию. В случае отсутствия такового выдается сообщение об ошибке.
Имя функции-метода обычно состоит из имени универсальной функ- ции, точки и имени класса. Так, функция-метод print() для класса data.frame имеет имя print.data.frame(), а функция-метод по умол- чанию называется print.default().
Наследование при такой модели ООП происходит тривиальным об- разом: достаточно в качестве атрибута class использовать вектор дли- ны 2 и больше. Например, в случае если бы нам захотелось создать свой собственный объект, со структурой, похожей на таблицу данных, то мы могли бы использовать в качестве атрибута class нечто типа c("custom.data.frame", "data.frame")
Таким образом, мы могли бы переопределить часть функций-методов для нашего класса (например, print() и summary()), по при этом оста- вить остальные функции от таблицы данных (например, [).
Получить список всех методов для данной универсальной функции можно при помощи methods:
> methods(summary)
[1]
summary.aov summary.aovlist summary.aspell*
[4]
summary.connection summary.data.frame summary.Date
[7]
summary.default summary.ecdf*
summary.factor
[10] summary.glm summary.infl summary.lm
[13] summary.loess*
summary.manova summary.matrix
Non-visible functions are asterisked

250
Основы программирования в R
Сразу же отметим, что файлы справки для универсальной функ- ции и функции-метода, вообще говоря, отличаются, поэтому, напри- мер, справку по методу summary() для класса Date следует вызывать,
используя имя метода: ?summary.Date.
Подробную информацию о модели ООП S3 можно получить в раз- деле справки S3Methods, по модели S4 — в разделе Methods.

Приложение Г
Выдержки из документации R
Это приложение поможет глубже разобраться в структуре R. Вдум- чивый и заинтересованный читатель найдет здесь много полезного, осо- бенно из областей создания функций и графиков. В качестве источника мы взяли английский текст «Introduction to R» — часть официальной документации, распространяемой на сайте программы, сократив неко- торые разделы, в том числе те, которые уже были освещены в преды- дущих главах и приложениях.
Г.1. Среда R
R
представляет собой набор программных средств для работы с дан- ными, вычислений и графического отображения. Среди прочего воз- можны:
• эффективная обработка и хранение данных;
• набор операторов для обработки матриц;
• цельная, непротиворечивая, комплексная коллекция утилит для анализа данных;
• графические средства для анализа данных и визуализации непо- средственно на компьютере или при выводе на печать;
• хорошо развитый, простой и эффективный язык программиро- вания (под названием «S»), который включает условия, циклы,
определенные пользователем рекурсивные функции и возможно- сти ввода-вывода. (Большинство поддерживаемых системой функ- ций сами написаны на языке S.)
Термины «окружение»/«среда» введены, чтобы подчеркнуть нали- чие полностью спланированной и непротиворечивой системы, а не по- степенно возникшего конгломерата весьма специфических и негибких утилит, как это часто бывает с другим программным обеспечением ана- лиза данных.

252
Выдержки из документации R
R
— это средство разработки новых методов интерактивного анализа данных. Он быстро разрабатывается и расширяется большой коллекци- ей пакетов.
Г.2. R и S
R
можно рассматривать как реализацию языка S, который был раз- работан в компании «Bell Laboratories» Риком Бекером, Джоном Чам- бером и Алланом Вилксом и который лежит в основе S-Plus.
Документация S/S-Plus, как правило, тоже может быть использова- на с R, если помнить о различиях между реализациями S.
Г.3. R и статистика
В нашем описании среды R не упоминается о статистике, но многие люди используют R в качестве статистической системы. Мы предпо- читаем думать о нем как об окружении, в котором были реализованы многие классические и современные статистические методы. Некото- рые из них встроены в базовое окружение R, но многие поставляется как пакеты. Есть около 25 пакетов, поставляемых с R (так называемые
«стандартный» и «рекомендованный» наборы пакетов), гораздо больше можно получить через CRAN (http://CRAN.R-project.org) и из дру- гих источников. Более подробно информацию о пакетах мы рассмотрим ниже.
Существует важное различие между философией в S (и, следова- тельно, R) и других основных статистических систем. В S статистиче- ский анализ, как правило, выполняется в виде серии шагов, с сохра- нением промежуточных результатов в объектах. Так, если SAS и SPSS
выведут обильные результаты процедуры регрессионного или дискри- минантного анализа, R выведет минимум результатов и сохранит вывод в объект для последующего использования.
Г.4. Получение помощи
R
имеет встроенную команду help() по аналогии с командой man в UNIX. Чтобы получить дополнительную информацию о какой-либо конкретной функции, например solve(), нужно ввести help(solve).
Альтернативный вариант — ?solve.
Для наименования, обозначенного специальными символами, аргу- мент должен быть помещен в двойные или одиночные кавычки, что превращает его в строку символов. Это также необходимо для некото-

Команды R
253
рых слов и знаков, имеющих синтаксическое значение, включая if и for
. Пример — help("[[").
Любая форма кавычек может быть использована, чтобы экраниро- вать другие кавычки, как в строке "It’s important". Мы будем при- держиваться по возможности использования двойных кавычек.
На большинстве установленных R-систем доступна справка в фор- мате HTML, достаточно выполнить команду help.start() — и будет запущен веб-браузер, что позволит просматривать страницы помощи в режиме гипертекста. В UNIX последующие help() запросы будут на- правляться в HTML-вариант системы помощи. Ссылка «Поисковая си- стема и ключевые слова», доступная на странице, загружаемой после выполнения help.start(), является особенно полезной, поскольку со- держит высокоуровневое оглавление, служащее для поиска доступных функций.
Команда help.search() позволяет искать подсказку различными способами: выполните ?help.search для того, чтобы узнать подробно- сти. Примеры по теме страницы помощи можно, как правило, запустить командой example(тема).
Windows-версии R имеют и другие дополнительные системы помо- щи — воспользуйтесь ?help, для того чтобы узнать подробности.
Г.5. Команды R
Технически R является языком выражений с очень простым син- таксисом. Он учитывает регистр, как и большинство других программ
UNIX. Так, «А» и «а» — это различные символы и будут обозначать различные переменные. Набор символов, которые могут быть исполь- зованы как имена в R, зависит от операционной системы и страны, в которых будет запущен R (технически говоря, от используемой локали).
Обычно разрешены все алфавитно-цифровые символы вместе с «.» и
«_», с ограничением, что имя должно начинаться с «.» или буквы, а если оно начинается с «.», то второй символ не должен быть цифрой.
Простые команды состоят из выражений либо присвоений. Если вы- ражение вводится как команда, оно вычисляется, выводится (если спе- циально не сделано невидимым), и результат теряется. Присвоение так- же вычисляет выражение и передает значение переменной, но результат автоматически не выводится.
Команды разделяются либо точкой с запятой («;»), либо переводом строки. Простые команды могут быть сгруппированы в единое состав- ное выражение фигурными скобками («{» и «}»). Комментарии могут быть практически где угодно, начинаются с символа решетки («#), при этом все до конца строки является комментарием.

254
Выдержки из документации R
Если команда не завершена в конце строки, R выдаст особое при- глашение, по умолчанию
+
во второй и последующих строках и продолжит ожидать ввода, пока команда не будет синтаксически завершена. Это приглашение может быть изменено пользователем.
Командные строки, набираемые в консоли, ограничены 1024 байта- ми (не символами!).
Г.6. Повтор и коррекция предыдущих команд
Во многих версиях UNIX и Windows R предусматривает механизм восстановления и повторного выполнения предыдущей команды. Вер- тикальные стрелки на клавиатуре можно использовать для прокрут- ки вперед и назад по истории команд. Когда команда найдена таким способом, курсор может перемещаться внутри команды с помощью го- ризонтальных стрелок, можно удалять символы при помощи клавиши

или добавлять при помощи остальных клавиш.
Возможности повтора и редактирования в UNIX являются гибко настраиваемыми. Вы можете узнать, как это сделать, прочитав систем- ное руководство по readline (под Linux это можно сделать, набрав в консоли «man readline»).
Г.7. Сохранение данных и удаление объектов
Записи, которые создает R и которыми он манипулирует, известны как «объекты». Это могут быть переменные, массивы чисел, строки символов, функции или более сложные конструкции, построенные из этих компонентов.
В ходе сессии R создаются и хранятся именованные объекты. Ко- манда
> objects()
так же, как и ls(), может быть использована для отображения на- званий объектов, которые в настоящее время хранятся в R. Набор объ- ектов, который в настоящее время хранится, называется «рабочее про- странство». Чтобы удалить объекты, есть функция rm():
> rm(x, y, z)

Внешнее произведение двух матриц
255
Если нужно удалить все созданные в течение сессии объекты (на- пример, для того чтобы не выходить и опять входить в R), то можно выполнить команду (осторожно, не удалите нужные вам объекты!)
> rm(list=ls())
Все объекты, созданные в ходе сессий R, могут быть сохранены в файл для использования в последующих сессиях. В конце каждой сес- сии R вам предоставляется возможность сохранить все имеющиеся в настоящее время объекты. Если вы подтвердите, что хотите этого, объ- екты записываются в файл .RData в текущем каталоге, а строки ко- манд, использованных в сессии, сохраняются в файл .Rhistory.
Если R будет запущен позже из этого каталога, то рабочее простран- ство будет перезагружено из файла .RData. Одновременно загрузится связанная история команд из .Rhistory.
Мы рекомендуем вам использовать отдельный рабочий каталог для каждого из анализов, проведенных в R.
Если команды хранятся во внешнем файле, например commands.r в поддиректории work, они могут быть выполнены в любой момент с помощью команды source("work/commands.r").
Функция sink("record.lis") будет направлять весь последующий вывод консоли во внешний файл, record.lis. Команда sink() восста- новит вывод в консоль.
Г.8. Внешнее произведение двух матриц
Важной операцией на матрицах является внешнее произведение. Ес- ли a и b — две числовые матрицы, то их внешнее произведение — это матрица, чей вектор размерностей состоит из последовательности эле- ментов двух исходных векторов размерности (порядок важен!), а вектор данных получают, рассчитывая все возможные произведения элементов вектора данных a с элементами вектора данных b. Внешнее произведе- ние выполняет специальный оператор %о%:
> a=b=array(1:24, dim=c(3,4,2))
> ab <- a %o% b
Альтернатива:
> ab <- outer(a, b, "*")
Функция умножения может быть заменена произвольной функци- ей двух переменных. Например, для того чтобы вычислить функцию

256
Выдержки из документации R
f(x; y) = cos(y)/(1 + x^2)
на регулярной сетке значений с х и у ко- ординатами, определенными векторами х и у соответственно, мы могли бы действовать следующим образом:
> x=y=1:10
> f <- function(x, y) cos(y)/(1 + x^2)
> z <- outer(x, y, f)
Кстати, внешнее произведение двух обычных векторов является мат- рицей с двойным индексом (то есть матрицей с рангом как минимум 1).
Заметьте, что оператор внешнего произведения не коммутативен (от пе- ремены мест множителей результат меняется).
Г.9. c()
Следует отметить, что в то время как cbind() и rbind() являются функциями объединения, которые учитывают параметр dim, базовая функция c() не учитывает, а наоборот — снимает со всех численных объектов параметры dim и dimnames. Это иногда удобно.
Естественным способом привести матрицу обратно к простому век- торному объекту является использование as.vector():
> vec <- as.vector(trees)
Однако аналогичный результат может быть достигнут и путем ис- пользования c() с только одним аргументом:
> vec <- c(trees)
Г.10. Присоединение
Конструкция с использованием $, такая как accountants$statef, не так уж и удобна. Полезной возможностью будет каким-то образом сде- лать компоненты списка или таблицы данных временно видимыми как переменные под их собственными именами, без необходимости каждый раз указывать название списка.
Предположим, lentils является таблицей данных с тремя перемен- ными (столбцами) lentils$u, lentils$v, lentils$w. Подключаем ее ко- мандой attach():
> lentils <- data.frame(u=1:10, v=11:20, w=21:30)
> attach(lentils)
scan()
257
Тем самым мы помещаем таблицу данных в путь поиска на пози- цию 2 и подразумеваем отсутствие каких-либо объектов с именами u, v или w в позиции 1. С этого момента такие присвоения, как u <- v + w не заменяют компонент u таблицы данных, но маскируют ее другой переменной u рабочего каталога на позиции 1 пути поиска. Чтобы из- менить переменные в самой таблице данных, можно прибегнуть к $- обозначениям:
> lentils$u <- v + w
Однако новое значение компонента u не будет видно до тех пор, пока таблица данных не будет отсоединена и присоединена снова.
Чтобы отсоединить таблицу данных, используют функцию detach().
Говоря точнее, это выражение отсоединяет от пути поиска записи, на- ходящиеся в настоящее время в позиции 2. Таким образом, в данном контексте переменные u, v и w будут больше не видны. Записи на по- зициях больше чем 2 можно отсоединить путем указания их номера в detach
, но гораздо безопаснее всегда использовать название, например detach(lentils)
или detach("lentils")
Г.11. scan()
Предположим, что векторы данных имеют одинаковую длину и счи- тываются параллельно. Далее предположим, что есть три вектора, пер- вый символьного типа и оставшиеся два численного типа, а файл назы- вается input.dat. Первым шагом является использование scan() для считывания трех векторов в виде списка следующим образом:
> inp <- scan("data/input.dat", list("", 0, 0))
Второй аргумент является фиктивным списком, который задает тип считываемых трех векторов. В результате получен список, компонента- ми которого являются три считанных вектора. Для разделения данных на три отдельных вектора используем назначение типа:
> label <- inp[[1]]; x <- inp[[2]]; y <- inp[[3]]
Удобнее, чтобы фиктивный список имел поименованные компонен- ты, в этом случае имена могут использоваться для доступа к считанным векторам. Например:
> inp <- scan("data/input.dat", list(id="", x=0, y=0))

258
Выдержки из документации R
Если вы хотите получить доступ к переменным по отдельности, они могут быть реорганизованы в переменные текущей таблицы данных:
> label <- inp$id
> x <- inp$x
> y <- inp$y
Или список может быть присоединен в позицию 2 пути поиска.
Если второй аргумент является одиночным значением, а не списком,
считывается единый вектор, все компоненты которого должны быть одного типа, как и фиктивное значение.
> X <- matrix(scan("data/input.dat", list("",0,0)), ncol=3,
+ byrow=TRUE)
Г.12. R как набор статистических таблиц
В R есть весьма представительный набор статистических таблиц
(табл. Г.1). Любой функции, перечисленной в таблице, можно задать префикс d названию для получения плотности, р для кумулятивной плотности распределения, q для квантильной функции и r для гене- рации случайной выборки. Первый (основной) аргумент в указанных функциях: х для dxxx, q для pxxx, р для qxxx и n для rxxx (за исклю- чением rhyper и rwilcox, для которых задается nn). Все pxxx и qxxx функции имеют логические аргументы lower.tail и log.p, dxxx имеет параметр log.
Г.13. Область действия
Этот раздел содержит больше технических деталей, чем другие ча- сти этого документа, поскольку здесь описывается одно из основных различий между S-Plus и R.
Символы, которые встречаются в теле функции, могут быть разде- лены на три класса: формальные параметры, локальные переменные и свободные переменные. Формальные параметры функции — это те, ко- торые входят в список аргументов функции. Их значение определяется в процессе связывания фактических аргументов функции с формаль- ными аргументами. Локальные — это переменные, значения которых определяются вычислением выражений в теле функции. Переменные,
которые не являются формальными параметрами или локальными пе- ременными, называются свободными переменными. Если свободной пе- ременной присвоить локальную переменную, то она тоже станет ло- кальной. Рассмотрим следующее определение функции:

Область действия
259
Распределение
Функция Дополнительные аргументы
Бета beta shape1, shape2, ncp
Биноминальное binom size, prob
Коши-Лоренца cauchy location, scale
Хи-квадрат chisq df, ncp
Экспоненциальное exp rate
F (Фишера)
f df1, df2, ncp
Гамма gamma shape, scale
Геометрическое geom prob
Гипергеометрическое hyper m, n, k
Лог-нормальное lnorm meanlog, sdlog
Логистическое logis location, scale
Негативное биномиальное nbinom size, prob
Нормальное norm mean, sd
Пуассона pois lambda t (Стьюдента)
t df, ncp
Равномерное unif min, max
Вейбулла weibull shape, scale
Уилкоксона wilcox m, n
Таблица Г.1. Распределения, встроенные в R
> f <- function(x) {
+ y <- 2*x
+ print(x)
+ print(y)
+ print(z)
+ }
В этой функции х — формальный параметр, y является локальной переменной, а z является свободной переменной.
В R связывание свободной переменной решается сначала поиском в области, в которой функция была создана. Это называется «область действия». Сначала определим функцию cube():

260
Выдержки из документации R
> 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-PLUS
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 может быть ис- пользован для имитации банковского счета. Для функционирования банковского счета необходимо иметь баланс или итог, функции для сня- тия, функцию для создания депозитов и функции для определения те- кущего баланса. Это достигается путем создания трех функций внутри счета, а затем возвращения списка, содержащего их. Когда счет заво- дится, он принимает численный аргумент total и возвращает список,
содержащий все три функции. Поскольку эти функции определяются в окружении, которое содержит total, они будут иметь доступ к его значению.
Специальный оператор присваивания, «<<-», используется для из- менения значения, связанного с total. Этот оператор «смотрит назад»

Область действия
261
в поисках такого окружения, которое содержит символ 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)
30 withdrawn. Your balance is 70
> ross$balance()
Your balance is 70
> robert$balance()
Your balance is 200
> ross$deposit(50)
50 deposited. Your balance is 120

262
Выдержки из документации R
> ross$balance()
Your balance is 120
Г.14. Настройка окружения
Пользователи могут настраивать свои окружения несколькими спо- собами. Существует системный файл настроек запуска (инициализа- ции), каждый рабочий каталог также может иметь свои собственные специальные файлы инициализации. Наконец, могут быть использова- ны специальные функции .First() и .Last().
Место расположения системного файла инициализации берется из значения переменной среды R_PROFILE. Если эта переменная не уста- новлена, используется файл Rprofile.site в подкаталоге etc домаш- ней директории R. Этот файл должен содержать команды, которые вы хотите исполнять каждый раз, когда запускаете R в вашей систе- ме. Второй, индивидуальный профайл с именем .Rprofile может быть размещен в любом каталоге. Если R запускается в этом каталоге, то файл будет считан. Этот файл предоставляет индивидуальным поль- зователям контроль над их рабочим окружением и дает в различных рабочих каталогах возможность отличающихся процедур запуска. Если файла .Rprofile нет в каталоге запуска, тогда R ищет файл .Rprofile в пользовательском домашнем каталоге и использует его (если он су- ществует).
Любая функция с именем .First() в любом из этих двух профай- лов или в .RData имеет особый статус. Она автоматически выполнится в начале R-сессии и может использоваться для инициализации среды. На- пример, определение в примере ниже изменяет приглашение системы на
$
и устанавливает другие «полезности», которые будут использоваться по умолчанию.
.First <- function() {
# $ как приглашение options(prompt="$ ", continue="+\t")
# формат чисел и область печати options(digits=5, length=999)
# графический драйвер x11()
# рисовать символом "+"
par(pch = "+")
# мои собственные функции source(file.path(Sys.getenv("HOME"), "R", "mystuff.R"))
# присоединить пакет

Графические функции
263
library(MASS)
}
Вот последовательность, в которой исполняются описанные выше файлы:
1. Rprofile.site;
2. .Rprofile;
3. .RData;
4. .First().
Определения в последующих файлах маскируют определения в пре- дыдущих файлах.
Если определена функция .Last(), она выполняется в самом конце сессии:
.Last <- function() {
# небольшая мера безопасности graphics.off()
cat(paste(date(),"\nAdios\n"))
}
Г.15. Графические функции
Графические средства являются важной и очень гибкой частью сре- ды R. Можно использовать эти возможности для широкого спектра предопределенных статистических графиков, а также для того, чтобы создавать совершенно новые виды графиков.
Графические возможности могут быть использованы в интерактив- ном и пакетном режимах, но в большинстве случаев интерактивное ис- пользование более продуктивно. В момент запуска R включает драй- вер графического устройства, который открывает специальное окно для отображения интерактивной графики. Хотя это делается автоматиче- ски, полезно знать, что в UNIX используется команда X11(), а в Win- dows — команда windows().
Как только драйвер устройства запущен, рисующие команды R мо- гут быть использованы для производства различных графических отоб- ражений и для создания совершенно новых типов изображений.
Команды рисования делятся на три основные группы:

264
Выдержки из документации R
• Функции рисования высокого уровня создают новый рисунок на графическом устройстве, возможно, вместе с осями, метками, на- званиями и т. д.
• Функции рисования низкого уровня добавляют дополнительную информацию к существующим рисункам, такую как дополнитель- ные точки, линии и метки.
• Интерактивные графические функции позволяют интерактивно добавить либо получить информацию о существующем рисунке,
используя графический манипулятор, такой как, например, мышь.
Кроме того, R ведет список графических параметров, которыми можно манипулировать, чтобы изменить свой рисунок.
Этот раздел описывает только то, что известно как «базовая» гра- фика. Отдельная подсистема графики из пакета grid сосуществует с базовой — это более мощная, но более сложная в использовании систе- ма. Существует рекомендуемый пакет lattice, который построен на grid и обеспечивает способы для получения составных графиков.
Г.15.1.
plot()
Функции рисования высокого уровня призваны создать закончен- ный рисунок по данным, заданным как аргументы функции. При необ- ходимости автоматически создаются оси, метки и заголовки. Команды рисования высокого уровня всегда начинают новый рисунок, стирая те- кущий в случае необходимости.
Одна из наиболее часто используемых функций рисования в R —
это функция plot(). Это общая функция: вид производимого рисунка зависит от типа или класса первого аргумента.
> plot(x, y)
Если х и у являются векторами, plot(x, у) выдает коррелограмму y
по х. Тот же эффект может быть произведен заданием одного аргу- мента (вторая форма) либо как списка, содержащего два элемента х и у
, либо как матрицы из двух колонок:
> plot(x)
Если х является временным рядом, выводится график временного ряда. Если х является вектором чисел, выводится график значений век- тора по индексу вектора. Если х — это комплексный вектор, выводится график мнимой части векторных элементов по реальным частям.

Графические функции
265
> plot(f)
> plot(f, y)
Если f является фактором, а y является вектором чисел, то первый вариант создаст столбчатую диаграмму по f; а второй вариант выведет ящики-с-усами y для каждого уровня f.
> plot(df)
> plot(

expr)
> plot(y expr)
Если df — это таблица данных, y — любой объект, expr — список имен объектов, разделенных «+» (например, a + b + c), то в первых двух вариантах выводятся графики распределения по переменным в таблице данных (первый вариант) или по числу имен объектов (второй вариант). Третий вариант рисует y по каждому объекту, указанному в expr
Г.15.2. Отображение многомерных данных
R
предусматривает весьма полезные функции, представляющие мно- гомерные данные. Если Х — матрица чисел или таблица данных, то команда
> pairs(X)
выводит матрицу попарных коррелограмм для всех переменных,
столбцами Х, то есть каждый столбец Х отображается по всем другим столбцам X и результирующие n×(n−1) графиков будут выведены в ви- де матрицы, с расположенными симметрично относительно диагонали одинаковыми графиками.
Если рассматриваются три или четыре переменных, более полезной может быть функция coplot(). Если a и b — векторы чисел и с —
вектор чисел или фактор (все одинаковой длины), тогда команда
> coplot(a b | c)
производит ряд коррелограмм a по b для заданных значений c. Если c
представляет собой фактор, это просто означает, что a выводится по b для каждой градации c. Когда c — численный вектор, то он делится на ряд непрерывных интервалов и для каждого интервала a отображается по b для значений c из данного интервала. Количество и положение ин- тервалов можно контролировать с помощью аргумента given.values=
функции coplot(). Функция co.intervals() полезна для выбора ин- тервалов. Вы также можете использовать две переменные, например:

266
Выдержки из документации R
> coplot(a b | c + d)
рисует коррелограмму a на b для каждого совместного интервала группировки по c и d.
Обе функции, coplot() и pairs(), принимают аргумент panel=, ко- торый может быть использован для настройки типа графика в каждой из панелей. По умолчанию применяется points() (коррелограмма), но путем указания других низкоуровневых графических функций как зна- чения panel= можно выводить нужный тип графиков. Примером panel- функции, полезной для coplots(), является panel.smooth().
Г.15.3. Другие графические функции высокого уровня
Вот некоторые примеры:
> qqnorm(x)
> qqline(x)
> qqplot(x, y)
Это графики сравнения распределений. Первый вариант рисует чис- ленный вектор х в сравнении с ожидаемым нормальным распределени- ем квантилей, а второй добавляет прямую линию к такому графику,
проводя ее через квартили. Третий вариант выводит квантили х по y для сравнения их распределений.
> hist(x)
> hist(x, nclass=n)
> hist(x, breaks=b, ...)
выводят гистограммы вектора чисел х. Как правило, выбирается разумное количество интервалов группировки, но можно их задать пря- мо аргументом nclass. Кроме того, точки разбиения можно указать точно аргументом breaks. Если указан аргумент probability=TRUE,
столбцы вместо сумм представляют относительные частоты.
> dotchart(x, ...)
создает точечную диаграмму из данных, приведенных в х. В точеч- ной диаграмме ось у дает метки данных из х, а ось х отображает их величину. Это позволяет, например, легко отобрать все записи данных,
значения которых лежат в определенных диапазонах.
> image(x, y, z, ...)
> contour(x, y, z, ...)
> persp(x, y, z, ...)

Графические функции
267
рисуют графики трех переменных. График image() рисует сетку прямоугольников, используя различные цвета для отображения вели- чины z, график contour() рисует горизонтали, представляющие уровни z
, а график persp() рисует 3D-поверхность.
Г.15.4. Параметры функций высокого уровня
Есть ряд параметров, которые могут быть переданы высокоуровне- вым графическим функциям, например
..., add=TRUE
принуждает функцию действовать в качестве низкоуровневой гра- фической функции, накладывая свой график на текущий (это работает только для некоторых функций).
..., axes=FALSE
подавляет вывод осей, что бывает полезно для того, чтобы добавить собственные оси с помощью функции axis(). По умолчанию axes=TRUE,
что означает отображение осей.
..., log="x"
..., log="y"
..., log="xy"
Приводит х, у или обе оси к логарифмическому масштабу. Это сра- ботает для многих, но не всех видов графиков.
Аргумент
..., type контролирует тип выводимого графика, в частности
..., type="p"
выводит отдельные точки (принято по умолчанию),
..., type="l"
рисует линии,
..., type="b"
выводит точки, соединенные линиями вместе,

268
Выдержки из документации R
..., type="o"
рисует точки, перекрытые линиями,
..., type="h"
рисует вертикальные линии от точек до нулевого уровня оси,
..., type="s"
..., type="S"
рисует ступенчатую функцию. В первом варианте точка наверху, а во втором — внизу.
..., type="n"
не рисует ничего. Однако оси по-прежнему выводятся (это задано по умолчанию), и система координат создается в соответствии с дан- ными. Идеально подходит для создания участков последовательностью низкоуровневых графических функций.
..., xlab="строка"
..., ylab="строка"
Подписи осей х и у.
..., main="строка"
Название всего графика большим шрифтом, расположено в верхней части рисунка.
..., sub="строка"
Подзаголовок меньшим шрифтом, расположенный чуть ниже оси х.
Г.15.5. Низкоуровневые графические команды
Иногда высокоуровневые графические функции не дают именно та- кой график, какой вам нужен. Можно использовать низкоуровневые графические команды, чтобы добавить дополнительную информацию
(например, точки, линии или текст) к текущему рисунку.
Некоторые из наиболее полезных низкоуровневых функций:
> points(x, y)
> lines(x, y)

Графические функции
269
добавляют точки или связывающие линии к текущему графику. Для plot()
аргументы типа type= также могут быть переданы в эти функ- ции (по умолчанию "р" для points() и "l" для lines()).
> text(x, y, labels, ...)
добавляет текст в рисунок в точке, заданной х и у. Часто labels —
целочисленный или символьный вектор, в этом случае labels[i] вы- водится в точке (x[i], y[i]). Значение по умолчанию — 1:length(x).
Эта функция часто используется в таком сочетании:
> plot(x, y, type="n")
> text(x, y, names)
Графический параметр type="n" подавляет точки, но создает оси,
а функция text() поставляет специальные символы, которые заданы именами в символьном векторе для каждой из точек.
> abline(a, b)
> abline(h=y)
> abline(v=x)
> abline(lm.obj)
добавляют в текущий рисунок линии наклона b, отсекающие отрезок a
«h=y» может быть использовано для задания y-координаты высоты горизонтальной линии, проходящей через рисунок, а «v=x» аналогич- ным образом задает вертикальную линию. «lm.obj» может быть спис- ком с компонентами длины 2 (например, результатом функции подгон- ки модели), которые используются в качестве отсекающего отрезка и наклона (именно в таком порядке).
> polygon(x, y, ...)
строит многоугольник, определенный вершинами из (x, у), можно дополнительно затенить его штриховкой или закрасить его, если гра- фическое устройство позволяет закраску изображений.
> legend(x, y, legend, ...)
добавляет легенду к текущему графику в указанной позиции. На- чертание символов, стиль линий, цвета и т. п. определяются метками в символьном векторе описания. Должен быть задан по меньшей мере один аргумент v (вектор той же длины, как описание) с соответствую- щими значениями единиц измерения, а именно:

270
Выдержки из документации R
> legend(..., fill=v)
так определяются цвета для заполнения прямоугольников,
> legend(..., col=v)
так — цвета, которыми рисуются точки или линии.
> legend(..., lty=v)
Стиль линии
> legend(..., lwd=v)
Ширина линии
> legend(..., pch=v)
Выводимые символы (символьный вектор)
> title(main, sub)
добавляет заголовок main в начало текущего рисунка и подзаголо- вок sub внизу.
> axis(side, ...)
добавляет оси к текущему рисунку со стороны, заданной первым аргументом (от 1 до 4, считая по часовой стрелке снизу). Другие аргу- менты контролируют расположение оси внутри или рядом с рисунком и позиции меток. Для добавления в дальнейшем пользовательских осей полезно вызывать plot() с аргументом axes=FALSE.
Низкоуровневые графические функции, как правило, требуют неко- торой позиционной информации (например, х- и у-координаты), чтобы определить место для нового элемента рисунка. Координаты определя- ются в предыдущей высокоуровневой графической команде и выбира- ются на основе предоставленной информации.
Если нужны х и у, то достаточно задать один аргумент — список с элементами по имени x и y. Матрица с двумя столбцами также подхо- дит для ввода. Таким путем функции типа locator() (см. ниже) могут использоваться для интерактивного определения позиции на рисунке.

Графические функции
271
Г.15.6. Математические формулы
В некоторых случаях бывает полезно добавить математические сим- волы и формулы на график. Это можно сделать в R не символьной строкой в text, mtext, axis или title, а описанием выражения. На- пример, следующий код рисует формулу для биномиальной функции распределения:
> text(x, y, expression(paste(bgroup("(", atop(n, x), ")"),
+ p^x, q^{n-x})))
Более подробную информацию, включая полный перечень доступ- ных возможностей, можно получить в R с помощью команд:
> help(plotmath)
> example(plotmath)
> demo(plotmath)
Г.15.7. Интерактивная графика
R
также обеспечивает функции, которые позволяют пользователям получать или добавлять информацию на график с помощью мыши.
Простейшей из них является функция locator().
> locator(n, type)
ожидает щелчка левой кнопкой мыши. Это продолжается до тех пор, пока не будет выбрано n (по умолчанию 512) точек или нажата любая другая кнопка мыши. Аргумент type применим для вывода от- меченных точек и действует так же, как на высокоуровневые графиче- ские команды; по умолчанию вывод отсутствует. locator() возвращает координаты отдельных точек как список с двумя компонентами x и y.
locator()
обычно вызывают без аргументов. Это особенно полезно для интерактивного выбора позиции для графических элементов, та- ких как описания и метки, когда трудно рассчитать заранее, куда надо пометить графический элемент. Например, чтобы поставить некоторый информативный текст вблизи точки-выброса, может быть полезна ко- манда
> text(locator(1), "Outlier", adj=0)
(Команда locator() будет проигнорирована, если текущее устрой- ство, например postscript, не поддерживает интерактивного взаимо- действия.)

272
Выдержки из документации R
> identify(x, y, labels)
позволяет пользователю выделить любую из точек с определенными координатами х и у путем вывода поблизости соответствующего компо- нента labels (или индекс точки, если labels отсутствует). Возвращает индексы выбранных точек, когда нажимают другую кнопку мыши.
Иногда мы хотим идентифицировать именно точки на графике, а не их координаты. Например, мы можем пожелать, чтобы пользователь выбрал некоторые интересующие наблюдения на графическом дисплее,
а затем обработать эти наблюдения разными способами. Задав ряд (x,
у)
координат двумя численными векторами х и у, мы могли бы исполь- зовать функцию identify() следующим образом:
> plot(x, y)
> identify(x, y)
Функция identify() сама не рисует, она просто позволяет пользо- вателю переместить курсор мыши и нажать левую кнопку мыши вбли- зи точки. Если возле указателя мыши есть точка, она будет помечена своим индексом (то есть своей позицией в х/y векторах), выведенным поблизости.
Можно также использовать строки (например, название случая) в качестве подписи, используя аргумент labels для identify(), или во- обще отключить выделение аргументом plot = FALSE. Когда работа с графиком прекращается (см. выше), identify() возвращает индексы выбранных точек; вы можете использовать эти индексы для извлече- ния отдельных точек из первоначальных векторов х и y.
Г.15.8.
par()
При создании графики, в частности для выступлений или публи- каций, R по умолчанию не всегда выводит именно то, что требуется.
Однако можно настроить практически каждый аспект вывода, исполь- зуя графические параметры. R поддерживает список из большого числа графических параметров, которые контролируют среди многих других такие вещи, как стиль линии, цвет, расположение рисунка и текста.
Каждый графический параметр имеет имя (например, «col», который контролирует цвет) и значение (например, номер цвета).
Отдельный список графических параметров поддерживается для каждого активного устройства, и каждое устройство, когда оно ини- циализировано, по умолчанию имеет набор параметров. Графические параметры можно задать двумя способами: либо постоянно, затронув все графические функции, связанные с текущим устройством, либо вре- менно, затрагивая только один вызов графической функции.

Графические функции
273
Функция par() используется для доступа к списку параметров и из- менению графических параметров для текущего графического устрой- ства.
> par()
без параметров возвращает список всех графических параметров и их значения для текущего устройства.
> par(c("col", "lty"))
Если аргумент — символьный вектор, команда возвращает только названные графические параметры.
> par(col=4, lty=2)
с именованными аргументами (или одним общим списком аргумен- тов) устанавливает значения для соответствующих графических пара- метров и возвращает первоначальные значения параметров как список.
При настройке параметров графики функцией par() изменение зна- чений параметров постоянно в том смысле, что все будущие вызовы гра- фических функций (от текущего устройства) будут зависеть от нового значения.
Заметим, что вызовы par() всегда влияют на значения графических параметров глобально, даже когда par() вызывается внутри функции.
Это часто нежелательное поведение — как правило, мы хотим устано- вить некоторые параметры графики для некоторых рисунков, а затем восстановить исходные значения, чтобы не повлиять на пользователь- скую сессию R. Вот как можно восстановить некоторые параметры, вре- менно сохраняя результат par():
> oldpar <- par(col=4, lty=2)
[... строим график ...]
> par(oldpar)
Чтобы сохранить и восстановить вообще все настраиваемые графи- ческие параметры, используем
> oldpar <- par(no.readonly=TRUE)
[... строим график ...]
> par(oldpar)

274
Выдержки из документации R
Графические параметры часто могут быть переданы в графические функции как именованные аргументы. Это действует так же, как пере- дача аргументов в функции par(), за исключением того, что изменения действуют только в течение срока действия вызова функции. Напри- мер:
> plot(x, y, pch="+")
производит коррелограмму, используя знак «+» и не изменяя сим- вол печати по умолчанию для будущих графиков.
Г.15.9. Список графических параметров
В следующих подразделах детализируются многие из широко ис- пользуемых графических параметров. В справочной документации све- дения по функции par() представлены кратко, здесь дан несколько более подробный вариант.
Графические параметры будут представлены в следующей форме:
..., имя = значение
(Заметим, что axes — это не графический параметр, а аргумент для нескольких методов plot; см. документацию к xaxt и yaxt.)
Графики в R состоят из точек, линий, текста и полигонов (запол- ненных областей). Графические параметры существуют для того, что- бы контролировать, как эти графические элементы будут нарисованы,
а именно:
..., pch="+"
Символ, который будет использоваться для рисования точек. Умол- чание различно для различных графических устройств, однако это, как правило, кружок. Выводимые точки, как правило, немного выше или ниже соответствующей позиции, за исключением ситуации, когда как символ вывода используется ".".
..., pch=4
Когда pch задается как целое число между 0 и 25 включительно,
получается специальный символ. Чтобы увидеть, какие это символы,
используйте команду
> legend(locator(1), as.character(0:25), pch = 0:25)

Графические функции
275
Символы с 21 по 25 могут показаться дублирующими предыдущие символы, но у них разные цвета: см. помощь по points() и приведенные примеры.
Кроме того, pch может быть символом или числом в диапазоне
32:255
, представляющем символ в текущем шрифте.
..., lty=2
Это — тип линии. Альтернативные стили линии не поддерживаются всеми графическими устройствами (и различаются у разных устройств),
но тип 1 — это всегда сплошная линия, линия типа 0 всегда невидима,
линии типов 2 и более являются точечными или штриховыми, или со- четаниями обоих типов.
..., lwd=2
Ширина линии. Желаемая ширина линий, кратная «стандартной»
толщине линии. Влияет на линии осей, а также линий, выводимых ко- мандой lines() и другими. Не все устройства это поддерживают, мно- гие имеют ограничения на ширину.
..., col=2
Это цвета, которые будут использоваться для точек, линий, текста,
заполненных областей и изображений. Номер из текущей палитры (см.
?palette
), или название цвета.
..., col.axis=
..., col.lab=
..., col.main=
..., col.sub=
Это цвета, которые будут использоваться соответственно для анно- тации осей, х и у меток, заголовка и подзаголовка.
..., font=2
Параметр, который определяет, какой шрифт использовать для все- го текста на графике. Если возможно, устройство вывода организует это так, что 1 соответствует простому тексту, 2 — выделенному, 3 — кур- сиву, 4 — выделенному курсиву, а 5 — символьному шрифту (включая греческие буквы).

276
Выдержки из документации R
..., font.axis=
..., font.lab=
..., font.main=
..., font.sub=
Шрифты, которые будут использоваться соответственно для анно- тации осей, х и у меток, заголовка и подзаголовка.
..., adj=-0.1
Юстировка текста относительно позиции вывода. 0 означает юсти- ровать влево, 1 означает юстировать вправо и 0.5 — центрировать гори- зонтально относительно позиции вывода. Фактическое значение означа- ет долю текста, которая появляется с левой стороны от позиции вывода.
Значение −0.1 оставляет между текстом и позицией вывода пробел в
10% от ширины текста.
..., cex=1.5
Масштаб символов. Значение — это желаемый размер символов тек- ста (включая выводимые символы) по отношению к размеру шрифта по умолчанию.
..., cex.axis=
..., cex.lab=
..., cex.main=
..., cex.sub=
Масштаб символов, который будет использоваться для аннотации оси, х и у меток, заголовков и подзаголовков.
Оси и шкалы
Многие высокоуровневые рисунки R имеют оси, вы также може- те самостоятельно конструировать оси низкоуровневыми графически- ми функциями axis(). Оси имеют три основных компонента: линию оси
(стиль линии, который контролируется графическим параметром lty),
шкалу (которая обозначает деление линии оси единицами измерения) и метки шкалы (которые обозначают единицы измерения). Две последние компоненты можно настроить следующими параметрами графики:
..., lab=c(5, 7, 12)
Первые два числа — это желаемое количество интервалов по х и у осям соответственно. Третье — желаемая длина меток оси, в символах
(включая запятую).

Графические функции
277
..., las=1
Ориентация меток оси. 0 означает «всегда параллельно оси», 1 озна- чает «всегда горизонтально» и 2 — «всегда перпендикулярно оси».
..., mgp=c(3, 1, 0)
Это — позиции компонентов оси. Первый компонент — это расстоя- ние от метки оси до позиции оси, в текстовых строках. Второй компо- нент – это расстояние до меток шкалы, и окончательный компонент –
это расстояние от позиции оси до линии оси (обычно ноль). Положи- тельные числа «уводят» за пределы региона рисования, отрицательные числа — внутрь региона.
..., tck=0.01
Длина меток шкалы как доля размера региона рисования. Когда tck невелик (менее 0.5), метки шкалы на осях х и у одинакового размера.
Значение 1 дает сетку линий. Отрицательные значения дают метки за пределами региона рисования. Используйте tck = 0.01 и mgp = c(1,
-1.5, 0)
для внутренних меток шкалы.
..., xaxs="r"
..., yaxs="i"
Стили для осей х и у соответственно. Со стилями "i" (внутренний)
и "r" (по умолчанию) метки шкалы всегда находятся внутри диапазона данных, однако стиль "r" оставляет небольшое пространство на краях.
(S имеет и другие стили, которые не были реализованы в R).
Г.15.10. Края рисунка
Одиночный рисунок в R называется «изображение» и включает ре- гион рисования, окруженный полями (возможно, содержащими метки осей, заголовки и т. д.).
Графические параметры, контролирующие формат изображения:
..., mai=c(1, 0.5, 0.5, 0)
Определяет ширину соответственно нижнего, левого, верхнего и пра- вого полей; измеряется в дюймах.
..., mar=c(4, 2, 2, 1)

278
Выдержки из документации R
Аналогично mai, за исключением того, что единица измерения — это текстовые строки.
mar и mai эквивалентны в том смысле, что настройка одного вызыва- ет изменение значения другого. Часто значения по умолчанию выбраны для этого параметра слишком большими; правый край требуется ред- ко, и верхнее поле не нужно, если нет названия. Нижнее и левое поля должны быть достаточными для размещения оси и меток масштаба.
Кроме того, размер по умолчанию выбирается без учета размера устройства вывода: например, использование устройства postscript()
с параметром height=4 приведет к рисунку, 50% которого составляют поля, если используются mai или mar по умолчанию.
Когда выводятся составные изображения (см. ниже), поля уменьша- ются, однако этого может быть недостаточно, когда на одной странице много изображений.
Г.15.11. Составные изображения
R
позволяет создать массив из n×m изображений на одной странице.
Каждое изображение имеет свои поля, а массив изображений может быть окружен наружными полями.
Графические параметры, связанные с составными изображениями,—
это:
..., mfcol=c(3, 2)
..., mfrow=c(2, 4)
Они устанавливают размер массива составных изображений. Пер- вый аргумент у них — это количество строк, а второй — число столбцов.
Единственная разница между ними в том, что установление mfcol вы- водит изображения по колонкам, а mfrow заполняет массив построчно.
Установка любого из этих показателей может сократить базовый размер символов и текста (контролируется при помощи par("cex")) и pointsize устройства вывода. В формате с двумя строками и столб- цами базовый размер уменьшается на 0.83, если есть три или больше строки или столбца, коэффициент уменьшения равен 0.66.
..., mfg=c(2, 2, 3, 2)
Это — позиция текущего изображения в составном окружении. Пер- вые два номера — это строка и столбец текущего составного изображе- ния; последние два числа — это строки и столбцы в составном массиве изображений. Используйте этот параметр для перехода между изобра- жениями в массиве. Для отображения разноразмерных изображений на одной и той же странице можно даже использовать отличающиеся от правильных значений значения для последних двух аргументов.

Графические функции
279
..., fig=c(4, 9, 1, 4)/10
Позиция текущего изображения на странице. Значения парамет- ров — это позиции левого, правого, верхнего и нижнего краев соот- ветственно, в процентах от размера страницы, измеряемого от нижнего левого угла. Пример соответствует изображению в нижнем правом углу страницы. Используйте этот параметр для произвольного позициониро- вания изображений на странице. Если вы хотите добавить изображение к текущей странице, используйте new=TRUE.
..., oma=c(2, 0, 3, 0)
..., omi=c(0, 0, 0.8, 0)
Размер внешних полей. Как mar и mai, первое измеряется в тексто- вых строках, а второе — в дюймах, начиная с нижнего поля и по часовой стрелке.
Внешнее поле особенно полезно для заметок на полях и т. д. Текст может быть добавлен к внешнему полю функцией mtext() с аргументом outer=TRUE
. По умолчанию внешних полей не существует.
Более сложные составные изображения могут быть выведены функ- циями split.screen() и layout(), а также с использованием пакетов grid и lattice.
Г.15.12. Устройства вывода
R
может генерировать графику (разного качества) почти для любого типа дисплея или устройства печати, но сначала он должен быть проин- формирован, с каким типом устройства нужно взаимодействовать. Это делается путем запуска «драйвера устройства вывода». Смысл драйве- ра устройства вывода состоит в преобразовании графических команд R
(«нарисовать линию», например) к такой форме, которую конкретное устройство вывода может понять.
Драйвер устройства вывода запускают, вызывая функцию драйвера устройства. Для каждого устройства графического вывода существует единственная функция драйвера устройства (введите help(Devices))
для получения полного списка. Например, ввод команды postscript()
перенаправляет весь последующий графический вывод на принтер, пре- образуя его в формат PostScript. Некоторые широко используемые драй- веры устройств вывода:
X11()
служит для использования с X11 — оконной системой UNIX- подобных ОС;
windows()
нужна для использования в Windows;

280
Выдержки из документации R
quartz()
используется в Mac OS X;
postscript()
работает для печати на принтерах PostScript, а также создания графических файлов PostScript;
pdf()
выводит PDF-файл, который может быть включен в другие PDF- файлы;
png()
выводит растровый файл PNG;
jpeg()
выводит растровый файл JPEG (этот формат лучше использо- вать только для рисунков-изображений).
Когда вы закончите работать с устройством вывода, убедитесь, что остановили драйвер устройства вывода командой dev.off(). Это га- рантирует, что устройство остановится правильным образом, например в случае печатного устройства это гарантирует, что каждая страница будет отправлена на принтер.
Г.15.13. Несколько устройств вывода одновременно
При профессиональном использования R зачастую бывает полезно иметь несколько графических устройств вывода, используемых одно- временно. Конечно, в любой отдельный момент времени только одно графическое устройство может принимать графические команды: оно обозначается как «текущее» устройство. Когда несколько устройств от- крыты одновременно, они образуют пронумерованную последователь- ность с именами, определяющими тип устройства вывода в каждой из позиций.
Каждый новый вызов функции драйвера устройства вывода откры- вает новое графическое устройство, что расширяет на одну позицию список устройств вывода. Это устройство становится текущим устрой- ством вывода.
> dev.list()
Эта команда возвращает количество и наименование всех активных устройств вывода. Устройство в позиции 1 списка всегда является null- устройством, которое вообще не принимает графических команд.
> dev.next()
> dev.prev()
возвращает номер и название, соответственно, последующего или предыдущего графического устройства.

Пакеты
281
> dev.set(which=k)
может быть использована для изменения текущего графического устройства на устройство в позиции k списка устройств вывода. Воз- вращает номер и метку устройства.
> dev.off(k)
закрывает графическое устройство в позиции k списка устройств вы- вода. Для некоторых устройств, таких как postscript, это будет либо немедленно распечатывать файл, либо корректно завершать файл для последующей печати, в зависимости от того, как было инициировано устройство.
> dev.copy(device, ..., which=k)
> dev.print(device, ..., which=k)
делает копию устройства k. Здесь устройство — это функция драй- вера устройства, например postscript (без скобок), в случае необхо- димости с дополнительными аргументами, назначенными посредством
«...».
dev.print()
работает аналогично dev.copy(), но копируемое устрой- ство немедленно закрывается.
> graphics.off()
закрывает все графические устройства, кроме null-устройства.
Г.16. Пакеты
Все функции и данные R хранятся в пакетах. Их содержимое ста- новится доступным, лишь когда пакет загружается. Это делается как для производительности, так и для помощи разработчикам, которые предохранены от конфликтов имен.
Чтобы узнать, какие пакеты установлены в вашей инсталляции, на- берите команду library() без аргументов. Для загрузки конкретного пакета (например, пакета boot) используйте такую команду:
> library(boot)
Пользователи, подключенные к Интернету, могут использовать фун- кции install.packages() и update.packages() для установки и обнов- ления пакетов.
Чтобы узнать, какие пакеты уже загружены, используйте

282
Выдержки из документации R
> search()
для отображения списка. Некоторые пакеты могут быть загружены,
но не доступны в этом списке: они будут включены в список, выводимый
> loadedNamespaces()
Чтобы увидеть список всех доступных тем в системе помощи, ка- сающихся установленных пакетов, используйте help.start(). Эта ко- манда запускает HTML-систему помощи, затем надо перейти на список пакетов в разделе «Ссылки».
Г.16.1. Стандартные и сторонние пакеты
Стандартные пакеты содержат базовые функции, которые позволя- ют R работать, а также наборы данных и стандартные статистические и графические функции, которые описаны выше. Они должны быть автоматически доступны в любой инсталляции R.
Существуют тысячи сторонних пакетов для R, написанных различ- ными авторами. Некоторые из этих пакетов реализуют специализиро- ванные статистические методы, другие предоставляют доступ к дан- ным или оборудованию, третьи призваны дополнять руководства. Неко- торые из них (рекомендованные, «recommended») распространяются с каждым бинарным дистрибутивом R. Большинство из них доступны для загрузки с CRAN (http://CRAN.R-project.org и его зеркала) и других хранилищ, например http://www.bioconductor.org.
Г.16.2. Пространство имен пакета
Пакеты должны иметь пространства имен. Пространство имен де- лает три вещи: оно позволяет автору пакета скрыть функции и данные,
предназначенные только для внутреннего использования, предотвраща- ет функции пакета от поломки, когда пользователь (или автор другого пакета) выбирает название, совпадающее с названием из пакета, а так- же предусматривает способ сослаться на объект в рамках конкретного пакета.
Например, t() — это функция транспонирования в R, но пользова- тели могут определять свои собственные функции с именем «t». Про- странство имен предохраняет переопределения пользователя и преры- вает все функции, которые пытаются транспонировать матрицу.
Есть два оператора, которые работают с пространством имен. Двой- ное двоеточие — оператор «::» — выбирает определения из определен- ного пространства имен. В примере выше функция транспонирования всегда будет доступна как base::t(), поскольку оно определяется в

Пакеты
283
базовом пакете. Таким способом можно получить только функции, ко- торые экспортируются из пакета.
Тройное двоеточие, оператор «:::», можно увидеть в некоторых местах кода R — он действует подобно оператору двойного двоеточия,
но обеспечивает доступ к маскированным объектам. Пользователи чаще используют функцию getAnywhere(), которая ищет сразу в нескольких пакетах.
Пакеты зачастую взаимосвязаны, и загрузка одного может потре- бовать другие, которые будут автоматически загружены. Операторы двоеточия, описанные выше, вызывают автоматическую загрузку соот- ветствующего пакета. Когда пакеты загружаются автоматически, они не добавляются в список поиска.

Приложение Д
Краткий словарь языка R
Здесь мы собрали примерно пятьдесят самых-самых, на наш взгляд,
необходимых команд, операторов и обозначений. Список мы постара- лись сделать как можно короче, для того чтобы эти команды было легче запомнить.
?
Помощь
<-
Присвоить то, что справа, тому, кто слева
[
Выбрать часть объекта
$
Вызвать элемент списка по имени anova()
Дисперсионный анализ apply()
Применить функцию к объекту as.character()
Конвертировать в текст as.numeric()
Конвертировать в числа boxplot()
Ящик-с-усами, боксплот c()
Соединить в вектор cbind()
Соединить в матрицу по колонкам chisq.test()
Тест хи-квадрат cor()
Корреляция между многими переменными colSums()
Просуммировать каждую колонку cor.test()
Корреляционный тест data.frame()
Сделать таблицу данных dotchart()
Точечный график (замена «пирогу»)

Краткий словарь языка R
285
example()
Вызвать пример работы команды file.show()
Показать файл function()
Сделать новую функцию head()
Показать первые строчки таблицы help()
Помощь hist()
Гистограмма legend()
Дополнение к графику: легенда length()
Длина переменной lines()
Дополнение к графику: линии lm()
Линейная модель log()
Натуральный логарифм max()
Наибольшее значение mean()
Среднее median()
Медиана min()
Наименьшее значение
NA
Пропущенное значение names()
Вывести имена элементов nrow()

1   ...   11   12   13   14   15   16   17   18   19


написать администратору сайта