Учимся программировать в R: логические операторы, if else, for и while

Программирование на RСоздание скриптов и функций в R зачастую требует навыки программирования, а именно: использования логических операторов (например, >= "больше или равно") и управляющих структур (if elsefor и while). Благодаря им мы можем задавать условия, при которых будет выполняться то или иное действие, а также определять порядок выполнения действий и их повторяемость.

Другими словами, управляющие структуры автоматизируют процессы анализа данных, прописав возможные сценарии и условия их выполнения. Программирование на языке R позволяет не только уменьшить код скрипта/функции, но и существенно сэкономить время, доверив всю рутинную работу компьютеру.

Логические операторы в R

Операторы в R можно разделить на две категории: арифметические и логические. Арифметическими операторами являются знакомые нам со школы знаки сложения, вычитания, умножения и деления, а также знак возведения в степень и модульные операции (+, -, *, /, ^, %% и %/%, соответственно). Логические операторы обычно используются при проверке условий и выдают значения: TRUE или FALSE. В языке R существует 9 логических операторов, без знания которых программирование не представляется возможным.

Оператор Описание
> Больше
>= Больше или равно
< Меньше
<= Меньше или равно
== Равно
!= Не равно
& Логическое И
| Логическое ИЛИ
! Логическое НЕ

Обратите внимание, что "=" и "==" - это два разных оператора: в то время как первый присваивает значение переменной, второй сравнивает их на предмет равенства и выдает результат в виде TRUE или FALSE. Давайте напишем несколько примеров используя логические операторы, чтобы понять как с ними работать.

# Верно ли утверждение, что 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 & b == 1331
[1] TRUE

В целом принцип простой: на левой стороне от логического оператора находится "значение/переменная 1", на правой - "значение/переменная 2", в то время, как сам оператор является критерием, по которому R "судит" о правильности утверждения. Если утверждение верно, то в командной строке будет выведено TRUE, если утверждение ложно - FALSE. Следует добавить, что логические операторы работают со всеми типами данных: от векторов до таблиц, что делает их незаменимым инструментом в стат. анализе.

a <- c(1,2,3,5,8,10)
a >= 5
[1] FALSE FALSE FALSE TRUE TRUE TRUE

b <- a[a >= 5]
b
[1] 5 8 10

Теперь мы знаем, что такое логические операторы и готовы к изучению второй части этой статьи - работе с управляющими структурами в R.

Программирование и управляющие структуры

Существует около десятка управляющих структур на которых базируется программирование в R. Среди них можно выделить три наиболее используемые: оператор условий if else и два типа циклов - for и while.

Оператор условий if else используется, когда есть два и более варианта развития сценария: если условие выполняется - "делай это", если не выполняется - "делай то". Суть же циклов в том, что они повторяют одно и то же действие несколько раз: в цикле while действие повторяется пока не выполнится условие цикла, а в цикле for - определенное пользователем количество раз.

Циклы while и for в RНа рисунке изображены три вида управляющих структур, где стрелки отображают поток данных. Если условие выполняется (TRUE), то поток данных движется вниз от условия, если нет (FALSE), то вправо и вниз. Как можно заметить в структурах типа while и for при выполнении условия, поток данных циркулирует по кругу: именно по этой причине их и называют циклами. Давайте разберем каждую из этих структур на практике!

Оператор условий if else в R

В языке программирования R оператор условий if else состоит из трех элементов:

  1. индикатор структуры: if, else или else if (в случае, когда условий больше одного)
  2. условие структуры, заключенного в круглые скобки (где находится условие для выполнения действия).
  3. тело структуры, заключенного в фигурные скобки (где находится код самого действия)

Пример 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 <- function(x){
  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 <- function(x){
  if(x >= 100){
    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 <- function(y){
 for(i in 1:100){
 y<-y+y*0.05
 }
 print(y)
}

run.10km(0.1)
[1] 13.15013

Оказалось, Ваш друг действительно прав: благодаря этой методике он сможет пробежать через 100 дней более 13 км за тренировку! Теоретически...

Пример 4: может тренироваться реже, но интенсивнее - цикл while

Однако, тренироваться ежедневно без выходных для начинающего - это неминуемый путь к физическому и психическому истощению. Чтобы у друга дни нагрузок чередовались с днями отдыха, давайте предложим ему альтернативную методику: тренироваться через день, но прибавляя к дистанции по 10% от предыдущей нагрузки (вместо 5%).

Рассчитаем, используя цикл while, через сколько дней друг начнет пробегать более 10 км за тренировку и выведем результат в виде таблицы каждая строчка которой отображает день тренировки и предполагаемую дистанцию.

alter.10km <- function(y){
  i <- 1
  Day <- i
  Distance <- y
  while(y <= 10){
    i <- i + 2 
    y<-y+y*0.1
    Day <- append(Day,i)
    Distance <- append(Distance,y)
   }
 DF <- data.frame(Day, Distance)
 return(DF)
}

results <- alter.10km(0.1)
tail(results, 3)
   Day  Distance
48  95  8.819749
49  97  9.701723
50  99 10.671896

Таким образом, наш друг с 99-го дня станет пробегать более 10 км за тренировку занимаясь реже, но интенсивнее! Выглядит, как более реалистичный вариант, но что скажет друг?

Заключение

Сегодня мы использовали простые и наглядные примеры, чтобы понять принцип и суть программирования на языке R. Знания логических операторов и структур управления позволят Вам реализовывать любые идеи в статистическом анализе, не ограничиваясь существующими решениями в R пакетах и интернете. Программирование на R не только экономит Ваше время, но и делает статистический анализ увлекательным и творческим занятием. Дерзайте!

Комментарии: 2
  1. Анастасия

    Здравствуйте! Пожскажите, пожалуйста, почему в задаче про бег (for) в конце в скобке стоит 0.1
    run.10km(0.1)
    [1] 13.15013

    Спасибо!)

    1. Samoedd (Автор записи)
      https://samoedd.com

      Здравствуйте, Анастасия!

      «Для этого создадим функцию run.10km и переменную y, обозначающую дистанцию тренировки (в км).»

      Т.к. друг начинал со 100 метров, а по условию мы договорились, что работаем с километрами, то вводим 0.1 км вместо 100 метров.

      Но можно ввести и 100 метров, просто программа тогда выдаст ответ тоже в метрах: на сотый день наш друг пробежит 13150.13 метров;-)

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *