Основы программирования: условные операторы

Копия images
Согласно Wiki, "условный оператор (условная инструкция, оператор ветвления) — оператор, конструкция языка программирования, обеспечивающая выполнение определённой команды (набора команд) только при условии истинности некоторого логического выражения, либо выполнение одной из нескольких команд (наборов команд) в зависимости от значения некоторого выражения... Существует две основные формы условных операторов: условный оператор (оператор if) и оператор многозначного выбора (переключатель, case, switch)". Говоря более простым языком, операторы типа if и switch используются в R для того, чтобы определенная часть кода запускалась только в тех ситуациях, когда это необходимо исследователю. При этом таких частей кода может быть несколько, как и условий, которые приводят к запуску каждой из них.
Условные операторы if
В R условные операторы типа if делятся на два вида - if-else и ifelse. Хотя последний из них скорее является сокращенным вариантом первого. Оператор if-else может принимать множество форм, которые, вместе с тем можно свести к трем основным:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  (a) if (cond) statement

  (b) if (cond) statement1 else statement2

  (c) if (cond1) {
          statement1
      } else if (cond2) {
          statement2
      } else {
          statement2
      }
Первую форму можно представить следующим образом: если есть условие (cond), наступает следствие (statement). Во второй форме имеем: если есть условие (cond), то наступает следствие 1 (statement1); во всех других случаях наступает следствие 2 (statement2). Для третей формы: если есть условие 1 (cond1), то наступает следствие 1 (statement1); если же есть условие 2 (cond2), то наступает следствие 2 (statement2); во всех других случаях наступает следствие 3 (statement3). Конечно же конкретных условий до else может быть максимум не две, а столько, сколько необходимо исследователю. Важно помнить, что в рамках одного запуска условного оператора может быть реализован только один из вариантов.
Рассмотрим простые примеры:
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  > words <- c("Питер","Гарри","Иван")
  > for_chek <- sample(words,1)
  > print(for_chek)
  [1] "Гарри"
  > if (for_chek == "Питер") cat(words[1], "Пенн")
  > if (for_chek == "Питер") cat(words[1], "Пенн") else
      print("Не Питер Пенн...")
  [1] "Не Питер Пенн..."
  > if (for_chek == "Питер") {
      cat(words[1], "Пенн")
    } else if(for_chek == "Гарри") {
      cat(words[2], "Поттер")
    } else {
      cat(words[3], "Дурак")
    }
  Гарри Поттер
Сначала мы создаем вектор с тремя именами. Далее случайным образом выбираем одно из них, записываем в скаляр for_chek и выводим его на экран с помощью функции print(). Это "Гарри". После этого идут три цикла. Первый (строка 16 синтаксиса) с помощью функции cat() выводит словосочетание "Питер Пенн" (более подробно о функции cat() смотри в завершении главы) в том случае, если for_chek равно "Питер". А поскольку for_chek равно "Гарри", то ничего не происходит. Второй цикл (строки 17 и 18 синтаксиса) выводит то же самое словосочетание для того же случая, во всех остальных выводит фразу - "Не Питер Пенн...". Последнее собственно и произошло. Наконец, третий цикл (строки 20-26 синтаксиса) выводит свое собственное словосочетание для каждого из имен. Здесь можно запустить этот код онлайн.
Что касается условного оператора в виде ifelse, то он представляет собой функцию, действие которой схоже с использованием условного оператора if-else формы (b). То есть в данном случае есть следствие для одного условия, а также еще одно следствие для всех остальных случаев. Общий вид функции следующий: ifelse(cond, statement1, statement2). Следовательно, первый агргумент - это условие для запуска первого следствия, второй - само это следствие, третий - следствие для всех остальных случаев.
Рассмотрим пример:
28
29
30
31
  > ifelse(for_chek == "Питер", 
           "Да это же Питер Пенн!!!",
           "Питера Пенна не существует!")
  [1] "Питера Пенна не существует!"
На экран выводится "Питера Пенна не существует!", так как предварительно в for_chek было записано слово "Гарри", а не "Питер".
Теперь рассмотрим более содержательный пример. Далее показана часть синтаксис для подготовки данных к регрессионному анализу:
32
33
34
35
36
37
  > for (j in (1:29)) {
  >   if (mean(test[,j])!=-999) {
  >     testNew <- cbind(testNew,test[,j])
  >     names(testNew)[length(testNew)] <- nameS[j]
  >   }
  > }
Суть этого синтаксиса заключается в том, чтобы каждую из 29 переменных в массиве, среднее значение которой не равно -999 (если среднее равно -999, это значит, что все ее значения пропущенны) записать в массив testNew. При этом, если переменная записывается, необходимо дать ей приемлемое имя, так как предварительно в процессе записи оно искажается.

Условные операторы switch
Базовый синтаксис для условных операторов этого вида выглядит так: switch(expr, ...). Здесь expr предполагает выражение, относительно которого будет выбрана одна из реализаций кода. Все возможные выражения и соответствующие реализации кода обозначены троеточием.
Рассмотрим простой пример:
38
39
40
41
42
43
44
45
46
  > words <- c("Питер","Иван")
  > for (i in words)
  >   print(switch
  >         (i,
  >          Питер  = "Питер Пенн",
  >          Гарри = "Гарри Поттер",
  >          Иван = "Иван Дурак"))
  [1] "Питер Пенн"
  [1] "Иван Дурак"
Здесь условный оператор (строки 40-44 синтаксиса) является аргументом функции print(). Использования одних функций (или других программных конструкций) в качестве аргументов других является распространенной практикой. Как видно, в зависимости от того, чем является выражение i, будет выведен один из трех вариатов (или не будет выведено ни одного, если i не равно "Питер", "Гарри" или "Иван"). Поскольку функция print() и условный оператор switch являются частью цикла for, синтаксис будет запущен для каждого элемента вектора words. При каждой итерации цикла вместо i последовательно будет подставлен каждый элемент упомянутого вектора, что приведет к реализации соответствующих вариантов функции print(). Онлайн вариант кода можно запустить здесь.
Подробнее о функции cat(). Функция cat() в качестве аргументов принимает как числовые, так и текстовые значения (в рамках одной функции можно использовать и первые, и вторые одновременно). Результатом функции является выведение в командной строке соответствующих аргументов в виде текста, в котором эти элементы (или аргументы) разделяются пробелом. В примере к этой главе в качестве одного из аргуметов выступает выражение words[1], которое равносильно первому элементу в векторе words (а это "Питер").

статью подготовил кандидат социологических наук Сергей Дембицкий

Вверх
blog comments powered by Disqus