Недавно мы рассказали, для чего нужен и что умеет язык R. Теперь познакомимся с ним поближе и посмотрим, из чего он состоит и как на нём пишутся программы. На самом деле здесь 9 конструкций, но 10 звучит круче.
Точка с запятой в R не ставится.
Комментарии
Для комментариев в R используют решётку, как и в большинстве языков:
# это комментарий # его можно оставлять на той же строке, что и команда, а можно выносить в отдельную строку
Переменные и векторы
Чтобы объявить переменную, достаточно объявить её имя и присвоить ей что-нибудь, а R сам разберётся, какой тип тут нужен:
Если говорить совсем точно, то в R существует много структур данных: векторы, матрицы, списки, факторы и так далее. Самым важным считается вектор — это набор элементов, у которых одинаковый тип данных.
Сами типы векторов такие:
- логический (logical),
- целочисленный (integer),
- вещественный (double),
- комплексный (complex),
- символьный (character),
- двоичные данные (raw).
С векторами можно делать любые операции из векторной алгебры. Если что — у нас есть отличный цикл про векторы и матрицы. Матрицы в R тоже есть.
Лекция 1. Анализ данных на R в примерах и задачах
Внешние модули
Сила языка R — во внешних модулях или пакетах, которые существенно расширяют возможности базового набора команд. Они позволяют быстрее строить нейросети, вторые — анализировать данные, а третьи заточены на работу со статистикой.
Чтобы подключить внешний модуль, используют команду library():
library(pipelearner) # подключаем модуль для разбиения данных на блоки, чтобы лучше обучать модель
Ввод и вывод
Для вывода значения переменной достаточно просто написать её имя:
x # выведет значение x y # выведет значение y
А для вывода сообщения нужна команда print(): print(«Привет, это журнал Код!»).
Если нужно вывести график функции, можно использовать стандартную команду plot() — она построит график в виде точек, гистограмм или соединит всё линиями.
plot(x,y) # в x и y — наборы значений
Так как R предназначен для работы с большими объёмами данных, то ввод данных идёт не с клавиатуры, а из файлов:
Но если нужен ввод с клавиатуры, используйте команду readline():
input
Присваивание и сравнение
Сравнение обозначается как обычно, двойным знаком равно:
a == 1331
А вот присваивания есть два, стрелка и знак равенства.
x = 15 y
Если не вдаваться в нюансы использования, то стрелка отвечает за глобальное использование переменной, чтобы она была видна всем, а знак равенства — за локальное использование, то есть внутри какой-то подпрограммы.
Условный оператор if
В нём никаких сюрпризов: фигурные скобки, как в JavaScript, и скобки для выражения, которое проверяем:
if(x >= 100 x < 1000)< y = 12 print(y) >else
Цикл for
А вот цикл for похож уже на Python с его диапазоном для организации шага цикла. Остальное всё то же самое — фигурные скобки тоже нужны для группировки нескольких команд:
R для каждого, Урок 1
for(i in 1:100)
Функции
Работают и объявляются точно так же, как и в других языках высокого уровня. Единственное отличие в том, что функция объявляется не сама по себе, а как бы отправляется в переменную (как стрелочная функция в JavaScript):
run.10km print(y) > run.10km(0.1)
Классы, методы и объекты
R — полностью объектно-ориентированный язык. Каждый элемент в нём — это объект, даже функции и таблицы. Поэтому всё, что работает в ООП (классы, методы и объекты), работает и в R, но на более сложном уровне абстракции.
В R можно посмотреть список всех доступных методов для любого объекта с помощью команды methods(). Например, если нам нужно понять, какие методы есть у команды plot(), которая рисует нам график, то нам нужно написать в консоли среды разработки: methods(plot)
В ответ мы получим все доступные методы:
[1] plot.acf* plot.data.frame* plot.decomposed.ts* [4] plot.default plot.dendrogram* plot.density* [7] plot.ecdf plot.factor* plot.formula* [10] plot.function plot.hclust* plot.histogram* [13] plot.HoltWinters* plot.isoreg* plot.lm* [16] plot.medpolish* plot.mlm* plot.ppr* [19] plot.prcomp* plot.princomp* plot.profile.nls* [22] plot.raster* plot.spec* plot.stepfun [25] plot.stl* plot.table* plot.ts [28] plot.tskernel* plot.TukeyHSD*
Кстати, метод default срабатывает, когда plot() получает на обработку объект неизвестного ей класса.
Источник: thecode.media
Учимся программировать в R: логические операторы, if else, for и while
Создание скриптов и функций в R зачастую требует навыки программирования, а именно: использования логических операторов (например, >= «больше или равно») и управляющих структур (if else, for и while). Благодаря им мы можем задавать условия, при которых будет выполняться то или иное действие, а также определять порядок выполнения действий и их повторяемость.
Другими словами, управляющие структуры автоматизируют процессы анализа данных, прописав возможные сценарии и условия их выполнения. Программирование на языке R позволяет не только уменьшить код скрипта/функции, но и существенно сэкономить время, доверив всю рутинную работу компьютеру.
Логические операторы в R
Операторы в R можно разделить на две категории: арифметические и логические. Арифметическими операторами являются знакомые нам со школы знаки сложения, вычитания, умножения и деления, а также знак возведения в степень и модульные операции (+, -, *, /, ^, %% и %/%, соответственно). Логические операторы обычно используются при проверке условий и выдают значения: TRUE или FALSE.
В языке R существует 9 логических операторов, без знания которых программирование не представляется возможным.
> | Больше |
>= | Больше или равно |
Меньше | |
Меньше или равно | |
== | Равно |
!= | Не равно |
=» и «= wp-block-preformatted»># Верно ли утверждение, что 11 в третьей степени не равняется 1111? 11^3 != 1111 [1] TRUE # 11 в третьей степени меньше 1111? 11^3 < 1111 [1] FALSE # То есть 11 в третьей степени это 11*11*11 # и оба этих выражения равняются 1331? a = 11^3 b = 11*11*11 a значение/переменная 1″, на правой — «значение/переменная 2», в то время, как сам оператор является критерием, по которому R «судит» о правильности утверждения. Если утверждение верно, то в командной строке будет выведено TRUE, если утверждение ложно — FALSE. Следует добавить, что логические операторы работают со всеми типами данных: от векторов до таблиц, что делает их незаменимым инструментом в стат. анализе.
a = 5 [1] FALSE FALSE FALSE TRUE TRUE TRUE b = 5] b [1] 5 8 10 Теперь мы знаем, что такое логические операторы и готовы к изучению второй части этой статьи — работе с управляющими структурами в R. Программирование и управляющие структурыСуществует около десятка управляющих структур на которых базируется программирование в R. Среди них можно выделить три наиболее используемые: оператор условий if else и два типа циклов — for и while. Оператор условий if else используется, когда есть два и более варианта развития сценария: если условие выполняется — «делай это», если не выполняется — «делай то». Суть же циклов в том, что они повторяют одно и то же действие несколько раз: в цикле while действие повторяется пока не выполнится условие цикла, а в цикле for — определенное пользователем количество раз. На рисунке изображены три вида управляющих структур, где стрелки отображают поток данных. Если условие выполняется (TRUE), то поток данных движется вниз от условия, если нет (FALSE), то вправо и вниз. Как можно заметить в структурах типа while и for при выполнении условия, поток данных циркулирует по кругу: именно по этой причине их и называют циклами. Давайте разберем каждую из этих структур на практике! Оператор условий if else в RВ языке программирования R оператор условий if else состоит из трех элементов:
Пример 1: покупай больше, плати меньше — if без elseДавайте создадим простейший вариант структуры if else, когда есть только одно условие при соблюдении которого, требуется выполнить дополнительное действие в сценарии. Допустим, в магазине акция: при покупке на сумму от 100$, предоставляется 12.5% скидка. Сколько мы в итоге потратим если наша покупка ( x ) была на сумму 120$? x = 120 if(x >= 100) x = x — x*12.5/100 print(x) > [1] 105 Итак, в скобках находится условие, что общая стоимость покупок будет меняться только в случае, если x >= 100 . Внутри фигурных скобок отображен код, иллюстрирующий механизм изменения финальной стоимости. Как Вы видите, индикатор else был не указан в конструкции. Мы его опустили, так как в случае, если x < 100 , то никаких действий производиться не будет. Следует также отметить, что для того, чтобы изменить показатель x , и проверить финальную цену, нам придется запускать весь код конструкции заново. Это непрактично, именно поэтому конструкцию if else чаще всего используют внутри функции. Давайте создадим и запустим функцию с оператором условий if else внутри. shop if(x >= 100) x = x — x*12.5/100 print(x) > > shop(120) [1] 105 shop(50) [1] 50 Пример 2: прогрессивная система скидок — индикатор else ifДобавим второе условие: если сумма покупок больше или равна 1000$, то магазин предоставит 25% скидку. Для этого условия мы будем использовать индикатор else if. В этом случае, нужно также изменить параметры первого условия, где x должно быть больше или равно 100, но меньше 1000. Если же ни первое, ни второе условие не соблюдается, то выведем на экран сообщение «No discounts» после финальной цены при помощи индикатора else. shop if(x >= 100 x < 1000) x = x — x*12.5/100 print(x) > else if(x >= 1000) x = x — x*20/100 print(x) > else print(c(x, «No discounts»)) > > shop(20) [1] 20 «No discounts» shop(200) [1] 175 shop(2000) [1] 1600 Также внутрь оператора условий if else можно вставить другой оператор if else, либо циклы while или for. Подобное свойство вложения управляющих структур позволяет реализовывать сложные многоуровневые сценарии (алгоритмы) на практике, создавая функции с несколькими аргументами, и множеством условий и циклов внутри. Циклы while и for в RРанее мы упоминали, что при неоднократном повторении кода в скрипте следует использовать R функции, чтобы уменьшить размер кода и сделать его более читабельным. Однако, в большинстве ситуаций это будет сделать невозможно без использования циклов внутри функции. Если есть условие, при исполнении которого потребуется повторить действие, используйте цикл while (перевод с англ.: «до тех пор, пока»). Если условия нет, но надо выполнить действие определенное количество раз, воспользуйтесь циклом for. Пример 3: уникальная методика бега — цикл forДопустим у нас есть друг который решил заняться бегом. До этого он не бегал и находится в ужасной физической форме: максимум сколько он смог пробежать за первую тренировку — 100 метров. Друг пообещал, что через 100 дней он за тренировку будет пробегать больше 10 км, так как он разработал собственную методику: он будет заниматься ежедневно и прибавлять по 5% к дистанции от предыдущей нагрузки. Проверим при помощи цикла for сработает ли его методика в теории. Для этого создадим функцию run.10km и переменную y , обозначающую дистанцию тренировки (в км). Внутри круглых скобок цикла for напишем что круг будет повторяться 100 раз, а внутри квадратных код вычислений дистанции для каждого дня. Дистанция последнего дня будет выделена на экран при использовании функции. run.10km for(i in 1:100) y > print(y) > run.10km(0.1) [1] 13.15013 Оказалось, Ваш друг действительно прав: благодаря этой методике он сможет пробежать через 100 дней более 13 км за тренировку! Теоретически. Пример 4: может тренироваться реже, но интенсивнее — цикл whileОднако, тренироваться ежедневно без выходных для начинающего — это неминуемый путь к физическому и психическому истощению. Чтобы у друга дни нагрузок чередовались с днями отдыха, давайте предложим ему альтернативную методику: тренироваться через день, но прибавляя к дистанции по 10% от предыдущей нагрузки (вместо 5%). Рассчитаем, используя цикл while, через сколько дней друг начнет пробегать более 10 км за тренировку и выведем результат в виде таблицы каждая строчка которой отображает день тренировки и предполагаемую дистанцию. alter.10km i Day Distance while(y i y Day Distance > DF return(DF) > results tail(results, 3) Day Distance 48 95 8.819749 49 97 9.701723 50 99 10.671896 Таким образом, наш друг с 99-го дня станет пробегать более 10 км за тренировку занимаясь реже, но интенсивнее! Выглядит, как более реалистичный вариант, но что скажет друг? ЗаключениеСегодня мы использовали простые и наглядные примеры, чтобы понять принцип и суть программирования на языке R. Знания логических операторов и структур управления позволят Вам реализовывать любые идеи в статистическом анализе, не ограничиваясь существующими решениями в R пакетах и интернете. Программирование на R не только экономит Ваше время, но и делает статистический анализ увлекательным и творческим занятием. Дерзайте! Комментарии: 17 Сентябрь 19, 2022 в 05:29 Уведомляем,Baм пpиcлaли лoтepeйный билeт. Пepeйдитe пo ccылкe дaлee ->> https://forms.yandex.com/cloud/63147fd81a862292755fbcc5/?hs=7158ed5412051f8736495dcc532eacc4! = China» . Ваш код должен выглядеть примерно так: new.df Вот ресурс, на котором кратко описано как отбирать данные (я на этом сайте не писал об этом еще), раздел Selecting Observations: Октябрь 13, 2020 в 10:35 Кирилл Спасибо! Через ваш код не получилось выбрать наблюдение, но получилось с помощью функции «subset». Подскажите, а как посмотреть среднее число заболевших по всем странам? Через функцию «mean» можно посмотреть только среднее число заболевших по всем странам.
Октябрь 13, 2020 в 11:31 Samoedd (Автор записи) Для этого надо использовать функцию aggregate . Апрель 29, 2020 в 19:53 Евгений Спасибо за статью! В примере с else if вы сказали что x должно быть больше или равно 100, но меньше 1000. А в коде нет такого. Второе условие else if у меня не срабатывает.
Май 2, 2020 в 20:18 Samoedd (Автор записи) Здравствуйте, Евгений! Спасибо за замечание, исправил: Март 27, 2020 в 06:05 Таня Добрый день! А вы ещё работаете в среде R ? Извините за вопрос (возможно наглость) смогли бы вы помочь мне с двумя практическими работами. Благодаря вашим темам 3 штуки я сделала. Спасибо заранее
Март 27, 2020 в 11:17 Samoedd (Автор записи) Пожскажите, пожалуйста, почему в задаче про бег (for) в конце в скобке стоит 0.1
Июль 2, 2018 в 10:30 Samoedd (Автор записи) Здравствуйте, Анастасия! «Для этого создадим функцию run.10km и переменную y, обозначающую дистанцию тренировки (в км).» Т.к. друг начинал со 100 метров, а по условию мы договорились, что работаем с километрами, то вводим 0.1 км вместо 100 метров. Но можно ввести и 100 метров, просто программа тогда выдаст ответ тоже в метрах: на сотый день наш друг пробежит 13150.13 метров;-) Источник: samoedd.com Введение в R. Разбираемся в анализе данных с использованием статистического пакетаВ прошлой статье из декабрьского номера я начал говорить об анализе данных и закончил на том, как быстро решить задачу линейной регрессии на R. Сегодня я более подробно расскажу об R как о языке программирования. Когда‑то это был язык для работы со статистикой, но сейчас его вполне можно считать языком общего назначения (хотя основную свою направленность он сохранил). Кто не верит, может заглянуть на страничку проекта Shiny, с помощью которого любой может создавать полноценные веб‑приложения на R. Ну да ладно, нас язык R интересует именно в той области, где он действительно хорош. В этой статье я расскажу о самых базовых объектах в языке и его особенностях. Кто‑то мудрый давно заметил, что самое хорошее в языке R — это то, что он был создан специалистами по статистике, а самое плохое — то, что он был создан специалистами по статистике :). Опустив вопросы установки R, с которыми довольно легко справиться (тем более что про это я немного уже писал в прошлой статье), приступим к изучению языка. Все, что вы хотели знать о функции, но боялись спроситьВ языке R доступна очень большая инфраструктура пакетов и, как следствие, совершенно невероятное количество функций для повседневного использования. Что делать, если ты знаешь название, но не помнишь правильное употребление функции? Решением станет очень приличный help, правильным образом встроенный в систему. Для того чтобы получить справку об использовании той или иной функции, достаточно набрать ?имя_функции . ВекторыНачнем с базовых объектов, из которых состоит язык. В большинстве языков программирования, с которыми тебе приходилось иметь дело, примитивными объектами являются числа, объекты булева типа и прочие действительно примитивные вещи. В языке R полно сюрпризов, и первый из них заключается в том, что примитивным объектом в R является вектор, то есть совокупность значений одной природы. К примеру, вектор вещественных чисел. Хочется спросить, а как быть с обычными числами? Скажем, с числом 10. Ответ на этот вопрос довольно прост — это вектор из одного элемента. Векторы бывают следующих типов:
По умолчанию числа в R — это вещественные числа, то есть числа с плавающей запятой. Для того чтобы явно указать R, что число, с которым ты собираешься иметь дела, целое, нужно добавить суффикс L. Например, 10L. Это легко иллюстрирует следующий код: [ 1 ] «integer» Здесь будет использоваться символ приглашения > , чтобы отличать код от ответа системы. В работе с числами существует специальный символ Inf для представления бесконечности. Следует обратить внимание на оператор присваивания < — . Рассмотрим следующий фрагмент:
> x # печатаем x В этом, казалось бы, очевидном фрагменте кода есть два важных момента: печатать можно, просто указывая имя переменной в строке или используя функцию, предназначенную для печати. Это довольно характерно для всех языков, в которых есть интерактивный интерпретатор REPL (Read — Evaluate — Print Loop). Функция print скорее используется для печати внутри других функций для отладки или просто для вывода какой‑либо информации. Что более важно и менее очевидно, строка [ 1] 10 , выводимая в качестве результата в R, говорит, что это первый (и единственный) элемент вектора. Число 1 в квадратных скобках выводится для удобства чтения. К примеру, если вектор не влезает в ширину экрана, то он разбивается на строки и числа перед каждой строкой — это индекс элемента вектора, с которого начинается данная строка. Для создания обычного вектора используется функция c : > x < — c ( 1 , 2 , 3 ) Так же как и во многих других языках, можно создавать векторы, указывая интервал значений: > x < — c ( 1 : 3 ) Казалось бы, результат тот же, однако все не совсем так. Так как это целочисленный интервал, содержимое второго вектора — это целые числа, а первого — вещественные. Что легко проверить с помощью функции typeof . В последнем случае еще можно писать просто x < — 1: 3 . Значения булева типа в языке R выглядят как TRUE и FALSE или просто T и F . Для того чтобы создать пустой вектор нужного типа, необходимо использовать функцию vector .
> x < — vector ( «numeric» , length = 10 ) Неявное преобразование типов в R хорошо иллюстрируется следующим примером:
> x < — c ( «a» , TRUE , 1. 3 ) Часто бывает необходимо воспользоваться явным преобразованием типов. Рассмотрим пример:
> as ( TRUE , «character» ) Два строчки делают в точности то же самое, однако с точки зрения читаемости кода Элементы вектора могут быть заименованы, это можно сделать следующим образом:
> v < — c ( x = 1. 0 , y = 2. 5 , z = -0. 1 ) МатрицыС векторами все довольно просто, давай теперь попробуем разобраться с другой полезной структурой данных — матрицами. Для создания матрицы есть специальная функция matrix :
> m < — matrix ( nrow = 2 , ncol = 3 ) Как видно, изначально создается пустая матрица. Для того чтобы получить размеры матрицы, существует специальный атрибут dim : > attributes ( m ) Следует отметить, что в смысле хранения двумерных объектов (массивов, матриц) все языки делятся на две группы: те, что хранят матрицы по строкам, такие как C и Java, и те, что хранят по столбцам, — это, к примеру, FORTRAN и R. В том, что это именно так, легко убедиться следующим образом:
> m < — matrix ( 1 : 6 , nrow = 2 , ncol = 3 ) Причем задавать двумерную структуру можно, просто добавляя атрибут dim к вектору:
> dim ( v ) < — c ( 2 , 3 ) Сверх того, строкам и колонкам матрицы можно давать имена:
> m < — matrix ( 1 : 4 , nrow = 2 , ncol = 2 ) В языке R существует также механизм создания двумерных структур из одномерных с помощью операций присоединения строки или столбца:
> y < — 11 : 13 О том, как работать с отдельными элементами структур данных, я напишу чуть позже, а пока продолжим разбираться с самими структурами. Списки и факторыВ этом разделе рассмотрим еще две полезные структуры данных. Первая — это, конечно, список. Дело в том, что часто приходится хранить данные разного типа в одном месте. Как мы знаем, вектор здесь не подходит, потому что его элементы должны быть одного типа, поэтому в R предусмотрены списки: > lst < — list ( «hello» , 1. 5 , TRUE , 1+2i ) Как видно, в списке содержится четыре элемента, и все они разного типа: строка, вещественное число, булево значение и комплексное число. Элементы списка можно именовать, как и элементы вектора: > l < — list ( a = «test» , b = 3. 14 ) Во многих языках программирования есть перечислимый тип данных. Он нужен для того, чтобы работать с данными, в качестве значения которых могут выступать элементы конечного множества. Когда такого типа в языке нет, этот вопрос решается с помощью констант для соответствующего набора значений. В языке R для обеспечения подобной функциональности есть специальный тип — фактор:
> x < — factor ( c ( «yes» , «no» , «yes» , «no» , «no» ) ) Здесь создается вектор факторов с двумя возможными значениями: yes и no. Можно, к примеру, подсчитать, сколько соответствующих значений есть в нашем векторе: Фрейм данных (Data Frame)Фрейм данных — один из самых полезных типов данных в R. Когда мы работаем с реальными табличными данными, именно этот тип представляет таблицы. В отличие от матриц, данный тип позволяет хранить различные типы данных в разных колонках. С точки зрения хранения этот тип данных можно представить как список специального вида, где элементами списка являются списки одинаковой длины (колонки). Для загрузки фрейма данных из CSV-файла существует функция read. csv , которая уже встречалась нам в предыдущей статье этой серии. Можно создать фрейм данных вручную, например так:
> x < — data. frame ( a = c ( F , F , T , T ) , b = c ( F , T , F , T ) , or = c ( F , T , T , T ) ) Помимо атрибута names , для фрейма данных также есть row. names :
> row. names ( x ) Доступ к элементамКак ты мог заметить, до сих пор я рассказывал лишь о том, какие бывают структуры данных, но ничего не сказал про то, как получать доступ к отдельным элементам или подмножествам. Посмотрим, как это работает, на простом примере с вектором:
> x < — c ( 11 , 21 , 31 , 41 , 11 , 21 , 31 ) Наверное, единственный комментарий, который требуется к данному примеру, — это то, что операция > работает как векторная операция и результатом ее выполнения будет вектор булевых значений, этот вектор может быть использован для выборки данных из вектора. При работе с матрицами также не возникает никаких сложностей, нужные строки и столбцы мы можем получить легко и непринужденно. К примеру, запись x[ 2, 3] — это элемент во второй строке и в третьем столбце, а x[ 1, ] и z[, 2] — это первая строка и второй столбец соответственно. По умолчанию эти операции возвращают вектор, а не матрицу, в которой одна строка или столбец, и если мы хотим, чтобы результатом выполнения данной операции была все‑таки матрица, пусть и другого размера, то нужно использовать дополнительный параметр x[ 1, , drop=FALSE] . С доступом к элементам списка все немного сложнее. Рассмотрим следующий пример:
> l < — list ( a = 0. 5 , b = 1 : 3 ) На этом примере достаточно хорошо видны особенности доступа к элементам в R. Как можно заметить, использование [[] ] не гарантирует соответствие типа возвращаемого значения изначальному, а в случае одинарных скобок [ ] возвращаемое значение также является списком. В этом смысле $ и [[] ] работают очень похоже. Хотя есть некоторая особенность — значение в двойных квадратных скобках может быть вычислено, а имя после знака $ — нет. Списки бывают вложенными, и доступ к их элементам осуществляется с помощью вложенных скобок, как и полагается: x[[ 1]][[ 3] ] , однако можно сделать запись чуть более понятной, используя функцию c . К примеру, последнее выражение можно записать как x[[ c( 1, 3)] ] . Причем использовать селектор с одной скобкой не получится (подумай почему). Управляющие структурыНадо заметить, что в данной статье я рассматриваю R именно как язык программирования, но на самом деле можно было бы взглянуть на него как на систему для работы со статистикой с типичными функциями для решения повседневных задач. Однако я предпочту быть консервативным в изложении и, как полагается после описания базовых типов, перейду к разговору об условных блоках и циклах. Начнем с условного оператора. Надо сказать, что здесь в R нет почти ничего особенного, но все‑таки: if ( x > 0 ) < y < — x >else < y < — — x > Ничего нового тут нет, и else может быть опущен. Хотя и тут не обошлось без несколько необычного поведения. В функциональных языках, таких как Haskell, конструкция if является выражением, а не оператором, то есть возвращает значение, а не изменяет состояние. В языке R эта идея также нашла себе место в следующей конструкции: y < — if ( x >0 ) < x >else < — x ># фигурные скобки можно опустить Последняя конструкция делает то же самое, что и предыдущая, только в функциональном стиле. Однако в функциональных языках выражение должно быть определено и поэтому наличие ветви else обязательно. Здесь же это не так, конструкция z < — if ( x < 0) -x вполне допустима, но значением этого выражения при x >0 будет специальное значение NULL . Для сравнения с этим значением можно использовать функцию is. null . Теперь стоит сказать пару слов о циклах. Циклы в R работают медленно, но когда мы имеем сравнительно небольшой объем данных, то использование циклов может быть вполне допустимо и даже удобно. С этой точки зрения R также мало отличается от других языков программирования. Начнем с цикла for , который реализует известную парадигму for-in.
x < — c ( «a» , «b» , «c» , «d» , «e» ) Как и полагается, цикл for-in реализует процесс итерации по вектору или последовательности, последний вариант более лаконичен, однако если нам каким‑либо образом нужны индексы, то хорошо бы иметь возможность создавать последовательность, соответствующую заданному вектору. Для этого в R предусмотрена специальная функция seq_along , принимающая в качестве аргумента вектор или список, для которых строится последовательность индексов. Таким образом, первый цикл можно было бы переписать в виде for( i in seq_along( x)) < . >. Для того чтобы сгенерировать последовательность заданной длины, можно воспользоваться функцией seq_len . Кстати, все эти вопросы легко решить известными средствами, используя лишь функцию вычисления длины length . Цикл while имеет вполне классическую форму while ( cond) < . >. Логические связки в R также выглядят стандартным образом: , || и ! . В дополнение к банальному while( TRUE) в R присутствует небанальный repeat < . >, выход из которого обеспечивает, как обычно, комбинация if и break . Для перехода к следующей итерации предусмотрен оператор с несколько неожиданным названием next . Как можно заметить, разделителей вроде точки с запятой между операторами в R нет. ФункцииКак уж без функций в приличном языке программирования? В самом общем виде определение функции выглядит следующим образом: Как и в функциональных языках, функции в R являются объектами класса. Это означает, что их можно передать в качестве аргумента в другую функцию и вернуть в качестве значения. Анонимные (лямбда) функции также присутствуют:
f < — function ( g ) < Здесь функция f принимает в качестве аргумента функцию g и возвращает функцию, которая имеет один формальный параметр x и дважды применяет к нему функцию g . Также в коде можно увидеть передачу анонимной функции в качестве аргумента, а полученный результат (композиция функций g и самой себя) применяется к числу 5. Таким образом, число 5 будет дважды возведено в квадрат. Порядок вычисления аргументов в R является отложенным (lazy), то есть аргумент не вычисляется, если он не нужен:
> f < — function ( x , y ) x * x Для того чтобы правильно работать с состоянием в случае замыканий, существует оператор Источник: xakep.ru
Загрузка ...
|