Функции в программировании на R на примере

Что такое функция в R?

A функцияВ среде программирования — это набор инструкций. Программист создает функцию, чтобы избежать повторяя ту же задачу или сократить complexность.

Функция должна быть

  • написано для выполнения определенных задач
  • может включать или не включать аргументы
  • содержать тело
  • может возвращать или не возвращать одно или несколько значений.

Общий подход к функции заключается в использовании аргументной части как затраты, накормить тело часть и, наконец, вернуть выходной. Синтаксис функции следующийwing:

function (arglist)  {
  #Function body
}

R важные встроенные функции

В R имеется множество встроенных функций. R сопоставляет входные параметры с аргументами функции либо по значению, либо по позиции, а затем выполняет тело функции. Аргументы функции могут иметь значения по умолчанию: если вы не укажете эти аргументы, R примет значение по умолчанию.
Внимание:
Посмотреть исходный код функции можно, введя в консоли имя самой функции.

R Важные встроенные функции

Мы увидим три группы функций в действии.

  • Общая функция
  • Математическая функция
  • Статистическая функция

Общие функции

Мы уже знакомы с общими функциями, такими как cbind(), rbind(),range(), sort(),order(). Каждая из этих функций имеет определенную задачу и принимает аргументы для возврата вывода. Фоллоwing важные функции, которые необходимо знать

функция diff()

Если ты работаешь над Временные ряды, вам нужно остановить серию, взяв их значения задержки, стационарный процесс обеспечивает постоянное среднее значение, дисперсию и автокорреляцию во времени. Это главным образом улучшает прогнозирование временного ряда. Это можно легко сделать с помощью функции diff(). Мы можем построить случайные данные временного ряда с тенденцией, а затем использовать функцию diff() для стабилизации ряда. Функция diff() принимает один аргумент, вектор, и возвращает подходящую запаздывающую и повторяемую разницу.

Внимание: Нам часто приходится создавать случайные данные, но для обучения и сравнения мы хотим, чтобы числа были одинаковыми на всех машинах. Чтобы гарантировать, что мы все генерируем одни и те же данные, мы используем функцию set.seed() с произвольными значениями 123. Функция set.seed() генерируется посредством процесса псевдослучайного числа. generator благодаря этому все современные компьютеры имеют одинаковую последовательность чисел. Если мы не будем использовать функцию set.seed(), у всех нас будет разная последовательность чисел.

set.seed(123)
## Create the data
x = rnorm(1000)
ts <- cumsum(x)
## Stationary the serie
diff_ts <- diff(ts)
par(mfrow=c(1,2))
## Plot the series
plot(ts, type='l')
plot(diff(ts), type='l')

Функция Дифф()

функция длина()

Во многих случаях мы хотим знать вектора для вычислений или для использования в цикле for. Функция length() подсчитывает количество строк в векторе x. Следующееwing коды импортируют набор данных автомобилей и возвращают количество строк.

Внимание: length() возвращает количество элементов в векторе. Если функция передается в матрицу или фрейм данных, возвращается количество столбцов.

dt <- cars
## number columns
length(dt)

Вывод:

## [1] 1
## number rows
length(dt[,1])

Вывод:

## [1] 50

Математические функции

R имеет множество математических функций.

оператор Описание
абс (х) Принимает абсолютное значение x
журнал (х, база = у) Логарифмирует x по основанию y; если основание не указано, возвращает натуральный логарифм
ехр (х) Возвращает экспоненту x
sqrt (х) Возвращает квадратный корень из x
факториал(х) Возвращает факториал x (x!)
# sequence of number from 44 to 55 both including incremented by 1
x_vector <- seq(45,55, by = 1)
#logarithm
log(x_vector)

Вывод:

##  [1] 3.806662 3.828641 3.850148 3.871201 3.891820 3.912023 3.931826
##  [8] 3.951244 3.970292 3.988984 4.007333
#exponential
exp(x_vector)
#squared root
sqrt(x_vector)

Вывод:

##  [1] 6.708204 6.782330 6.855655 6.928203 7.000000 7.071068 7.141428
##  [8] 7.211103 7.280110 7.348469 7.416198
#factorial
factorial(x_vector)

Вывод:

##  [1] 1.196222e+56 5.502622e+57 2.586232e+59 1.241392e+61 6.082819e+62
##  [6] 3.041409e+64 1.551119e+66 8.065818e+67 4.274883e+69 2.308437e+71
## [11] 1.269640e+73

Статистические функции

Стандартная установка R содержит широкий набор статистических функций. В этом уроке мы кратко рассмотрим наиболее важную функцию.

Основные статистические функции

оператор Описание
среднее (х) Среднее значение х
медиана (х) Медиана x
вар (х) Дисперсия x
сд(х) Стандартное отклонение x
масштаб(х) Стандартные оценки (z-оценки) x
квантиль(х) Квартили x
резюме(х) Сводка по x: среднее, минимальное, максимальное и т. д.
speed <- dt$speed
speed
# Mean speed of cars dataset
mean(speed)

Вывод:

## [1] 15.4
# Median speed of cars dataset
median(speed)

Вывод:

## [1] 15
# Variance speed of cars dataset
var(speed)

Вывод:

## [1] 27.95918
# Standard deviation speed of cars dataset
sd(speed)

Вывод:

## [1] 5.287644
# Standardize vector speed of cars dataset		
head(scale(speed), 5)

Вывод:

##           [,1]
## [1,] -2.155969
## [2,] -2.155969
## [3,] -1.588609
## [4,] -1.588609
## [5,] -1.399489
# Quantile speed of cars dataset
quantile(speed)

Вывод:

##   0%  25%  50%  75% 100%
##    4   12   15   19   25
# Summary speed of cars dataset
summary(speed)

Вывод:

##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
##     4.0    12.0    15.0    15.4    19.0    25.0

К этому моменту мы изучили множество встроенных функций R.

Внимание: Будьте осторожны с классом аргумента, т. е. числовым, логическим или строковым. Например, если нам нужно передать строковое значение, нам нужно заключить строку в кавычки: «ABC».

Написать функцию в R

В некоторых случаях нам нужно написать собственную функцию, потому что нам нужно выполнить конкретную задачу, а готовой функции не существует. Пользовательская функция включает в себя имя, Аргументы и еще один тело.

function.name <- function(arguments) 
{
    computations on the arguments	
    some other code
}		

Внимание: Хорошей практикой является присвоение определяемой пользователем функции имени, отличного от встроенной функции. Это позволяет избежать путаницы.

Функция с одним аргументом

В следующем фрагменте мы определяем простую квадратичную функцию. Функция принимает значение и возвращает квадрат значения.

square_function<- function(n) 
{
  # compute the square of integer `n`
  n^2
}  
# calling the function and passing value 4
square_function(4)

Код Пояснение

  • Функция называется Square_function; его можно называть как угодно.
  • Он получает аргумент «n». Мы не указан тип переменной, чтобы пользователь мог передать целое число, вектор или матрицу
  • Функция принимает входные данные «n» и возвращает квадрат входных данных. Когда вы закончите использовать функцию, мы можем удалить ее с помощью функции rm().

# после создания функции

rm(square_function)
square_function

На консоли мы видим сообщение об ошибке: Ошибка: объект «square_function» не найден, сообщающий, что функция не существует.

Оценка среды

В R охрана окружающей среды - это лыжных шлемов объектов, таких как функции, переменные, фрейм данных и т. д.

R открывает среду каждый раз, когда запрашивается Rstudio.

Доступная среда верхнего уровня — это глобальная среда, называемый R_GlobalEnv. И у нас есть местная среда.

Мы можем перечислить содержимое текущей среды.

ls(environment())

Результат

## [1] "diff_ts"         "dt"              "speed"           "square_function"
## [5] "ts"              "x"               "x_vector"

Вы можете увидеть все переменные и функции, созданные в файле R_GlobalEnv.

Приведенный выше список будет варьироваться в зависимости от исторического кода, который вы выполняете в R Studio.

Обратите внимание, что аргумент функции Square_function равен не в этой глобальной среде.

A new Для каждой функции создается среда. В приведенном выше примере функция Square_function() создает новую среду внутри глобальной среды.

Чтобы прояснить разницу между Глобальный и местная среда, давайте изучим следующееwing пример

Эта функция принимает значение x в качестве аргумента и добавляет его к определению y снаружи и внутри функции.

Оценка среды

Функция f возвращает результат 15. Это связано с тем, что y определен в глобальной среде. Любая переменная, определенная в глобальной среде, может использоваться локально. Переменная y имеет значение 10 во время всех вызовов функций и доступна в любое время.

Давайте посмотрим, что произойдет, если переменная y будет определена внутри функции.

Нам нужно удалить `y` перед запуском этого кода с помощью rm r

Оценка среды

Выход также равен 15, когда мы вызываем f(5), но возвращает ошибку, когда мы пытаемся напечатать значение y. Переменная y отсутствует в глобальной среде.

Наконец, R использует самое последнее определение переменной для передачи внутри тела функции. Давайте рассмотрим следующееwing пример:

Оценка среды

R игнорирует значения y, определенные вне функции, поскольку мы явно создали переменную ay внутри тела функции.

Функция с несколькими аргументами

Мы можем написать функцию с более чем одним аргументом. Рассмотрим функцию под названием «times». Это простая функция умножения двух переменных.

times <- function(x,y) {
  x*y
	}
times(2,4)

Вывод:

## [1] 8

Когда нам следует писать функцию?

Специалисту по данным приходится выполнять множество повторяющихся задач. Большую часть времени мы постоянно копируем и вставляем фрагменты кода. Например, настоятельно рекомендуется нормализовать переменную, прежде чем запускать обучение с помощью машины алгоритм. Формула нормализации переменной:

Формула для нормализации переменной

Мы уже знаем, как использовать функции min() и max() в R. Мы используем библиотеку tibble для создания фрейма данных. Tibble на данный момент является самой удобной функцией для создания набора данных с нуля.

library(tibble)
# Create a data frame
data_frame <- tibble(  
  c1 = rnorm(50, 5, 1.5), 
  c2 = rnorm(50, 5, 1.5),    
  c3 = rnorm(50, 5, 1.5),    
)

Мы выполним два шага для вычисления функции, описанной выше. На первом этапе мы создадим переменную с именем c1_norm, которая будет масштабировать c1. На втором этапе мы просто копируем и вставляем код c1_norm и меняем его на c2 и c3.

Деталь функции со столбцом c1:

Номинатор: : data_frame$c1 -min(data_frame$c1))

Знаменатель: макс(data_frame$c1)-min(data_frame$c1))

Следовательно, мы можем разделить их, чтобы получить нормализованное значение столбца c1:

(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))

Мы можем создать c1_norm, c2_norm и c3_norm:

Create c1_norm: rescaling of c1		
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
# show the first five values
head(data_frame$c1_norm, 5)

Вывод:

## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991

Оно работает. Мы можем скопировать и вставить

data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))

затем измените c1_norm на c2_norm и c1 на c2. То же самое делаем для создания c3_norm

data_frame$c2_norm <- (data_frame$c2 - min(data_frame$c2))/(max(data_frame$c2)-min(data_frame$c2))
data_frame$c3_norm <- (data_frame$c3 - min(data_frame$c3))/(max(data_frame$c3)-min(data_frame$c3))

Мы прекрасно изменили масштаб переменных c1, c2 и c3.

Однако этот метод подвержен ошибкам. Мы могли скопировать и забыть изменить имя столбца после вставки. Поэтому хорошей практикой является писать функцию каждый раз, когда вам нужно вставить один и тот же код более двух раз. Мы можем преобразовать код в формулу и вызывать ее всякий раз, когда это необходимо. Чтобы написать собственную функцию, нам нужно указать:

  • Название: нормализовать.
  • количество аргументов: нам нужен только один аргумент — столбец, который мы используем в наших вычислениях.
  • Тело: это просто формула, которую мы хотим вернуть.

Мы продолжим шаг за шагом создавать функцию нормализации.

Шаг 1) Мы создаем номинатор, который . В R мы можем хранить числитель в такой переменной:

nominator <- x-min(x)

Шаг 2) Мы вычисляем знаменатель: . Мы можем повторить идею шага 1 и сохранить вычисления в переменной:

denominator <- max(x)-min(x)

Шаг 3) Выполняем деление между числителем и знаменателем.

normalize <- nominator/denominator

Шаг 4) Чтобы вернуть значение вызывающей функции, нам нужно передать нормализацию внутри return(), чтобы получить выходные данные функции.

return(normalize)

Шаг 5) Мы готовы использовать функцию, заключив все в скобки.

normalize <- function(x){
  # step 1: create the nominator
  nominator <- x-min(x)
  # step 2: create the denominator
  denominator <- max(x)-min(x)
  # step 3: divide nominator by denominator
  normalize <- nominator/denominator
  # return the value
  return(normalize)
}

Давайте проверим нашу функцию с переменной c1:

normalize(data_frame$c1)

Он работает отлично. Мы создали нашу первую функцию.

Функции — это более комплексный способ выполнения повторяющейся задачи. Мы можем использовать формулу нормализации для разных столбцов, как показано ниже:

data_frame$c1_norm_function <- normalize (data_frame$c1)
data_frame$c2_norm_function <- normalize	(data_frame$c2)
data_frame$c3_norm_function <- normalize	(data_frame$c3)

Несмотря на то, что пример прост, мы можем сделать вывод о силе формулы. Приведенный выше код легче читать, и особенно можно избежать ошибок при вставке кодов.

Функции с условием

Иногда нам нужно включить в функцию условия, чтобы код мог возвращать разные выходные данные.

В задачах машинного обучения нам необходимо разделить набор данных между набором поездов и набором тестов. Набор поездов позволяет алгоритму учиться на данных. Чтобы проверить производительность нашей модели, мы можем использовать тестовый набор для возврата показателя производительности. В R нет функции для создания двух наборов данных. Для этого мы можем написать собственную функцию. Наша функция принимает два аргумента и называется Split_data(). Идея проста: мы умножаем длину набора данных (т. е. количество наблюдений) на 0.8. Например, если мы хотим разделить набор данных 80/20, а наш набор данных содержит 100 строк, тогда наша функция умножит 0.8 * 100 = 80. 80 строк будут выбраны в качестве наших обучающих данных.

Мы будем использовать набор данных о качестве воздуха для проверки нашей определяемой пользователем функции. Набор данных о качестве воздуха состоит из 153 строк. Мы можем увидеть это с помощью кода ниже:

nrow(airquality)

Вывод:

## [1] 153

Мы будем действовать следующим образом:

split_data <- function(df, train = TRUE)
Arguments:
-df: Define the dataset
-train: Specify if the function returns the train set or test set. By default, set to TRUE

Наша функция имеет два аргумента. Поезд аргументов является логическим параметром. Если для него установлено значение TRUE, наша функция создает набор данных поезда, остальныеwise, он создает тестовый набор данных.

Мы можем действовать так же, как и с функциейnormalise(). Мы пишем код так, как если бы это был одноразовый код, а затем помещаем все с условием в тело для создания функции.

Шаг 1:

Нам нужно вычислить длину набора данных. Это делается с помощью функции nrow(). Nrow возвращает общее количество строк в наборе данных. Мы называем переменную длину.

length<- nrow(airquality)
length

Вывод:

## [1] 153

Шаг 2:

Умножаем длину на 0.8. Он вернет количество строк для выбора. Должно быть 153*0.8 = 122.4.

total_row <- length*0.8
total_row

Вывод:

## [1] 122.4

Мы хотим выбрать 122 строки из 153 строк набора данных о качестве воздуха. Мы создаем список, содержащий значения от 1 до total_row. Мы сохраняем результат в переменной с именем Split

split <- 1:total_row
split[1:5]

Вывод:

## [1] 1 2 3 4 5

Split выбирает первые 122 строки из набора данных. Например, мы видим, что наша переменная Split собирает значения 1, 2, 3, 4, 5 и так далее. Эти значения будут индексом, когда мы будем выбирать строки для возврата.

Шаг 3:

Нам нужно выбрать строки в наборе данных о качестве воздуха на основе значений, хранящихся в переменной разделения. Это делается так:

train_df <- airquality[split, ] 
head(train_df)

Вывод:

##[1]    Ozone Solar.R Wind Temp Month Day
##[2]  51    13     137 10.3   76     6  20
##[3]  15    18      65 13.2   58     5  15
##[4]  64    32     236  9.2   81     7   3
##[5]  27    NA      NA  8.0   57     5  27
##[6]  58    NA      47 10.3   73     6  27
##[7]  44    23     148  8.0   82     6  13

Шаг 4:

Мы можем создать тестовый набор данных, используя оставшиеся строки 123:153. Это делается с помощью – перед разделением.

test_df <- airquality[-split, ] 
head(test_df)

Вывод:

##[1] Ozone Solar.R Wind Temp Month Day
##[2]  123    85     188  6.3   94     8  31
##[3]  124    96     167  6.9   91     9   1
##[4]  125    78     197  5.1   92     9   2
##[5]  126    73     183  2.8   93     9   3
##[6]  127    91     189  4.6   93     9   4
##[7]  128    47      95  7.4   87     9   5

Шаг 5:

Мы можем создать условие внутри тела функции. Помните, что у нас есть поезд аргументов, который по умолчанию имеет логическое значение TRUE, чтобы вернуть набор поездов. Чтобы создать условие, мы используем синтаксис if:

  if (train ==TRUE){ 
    train_df <- airquality[split, ] 
      return(train)		
  } else {
    test_df <- airquality[-split, ] 
      return(test)		
  }

Вот и все, мы можем написать функцию. Нам нужно изменить качество воздуха только на df, потому что мы хотим опробовать нашу функцию на любом фрейм данных, не только качество воздуха:

split_data <- function(df, train = TRUE){
  length<- nrow(df)
  total_row <- length *0.8
  split <- 1:total_row
  if (train ==TRUE){ 
    train_df <- df[split, ] 
      return(train_df)		
  } else {
    test_df <- df[-split, ] 
      return(test_df)		
  }
}

Давайте попробуем нашу функцию на наборе данных о качестве воздуха. у нас должен быть один набор поездов со 122 строками и тестовый набор с 31 строкой.

train <- split_data(airquality, train = TRUE)
dim(train)

Вывод:

## [1] 122   6
test <- split_data(airquality, train = FALSE)
dim(test)

Вывод:

## [1] 31  6