Що таке функція в R?
Функція , в середовищі програмування, являє собою набір інструкцій. Програміст створює функцію, щоб уникнути повторення одного і того ж завдання або зменшити складність.
Функція повинна бути
- написаний для виконання заданого завдання
- може включати чи не містити аргументи
- містять тіло
- може повертати або не повертати одне або кілька значень.
Загальний підхід до функції полягає у використанні частини аргументу як вхідних даних , подачі частини тіла та, нарешті, поверненні результату . Синтаксис функції такий:
function (arglist) {#Function body}
У цьому підручнику ми дізнаємось
- R важливі вбудовані функції
- Загальні функції
- Математичні функції
- Статистичні функції
- Функція запису в R
- Коли слід писати функцію?
- Функції з умовою
R важливі вбудовані функції
У R. є багато вбудованих функцій. R відповідає вашим вхідним параметрам з аргументами функції або за значенням, або за позицією, після чого виконує тіло функції. Аргументи функції можуть мати значення за замовчуванням: якщо ви не вказали ці аргументи, R прийме значення за замовчуванням.
Примітка : Переглянути вихідний код функції можна, запустивши в консолі назву самої функції.
Ми побачимо три групи функцій у дії
- Загальна функція
- Функція математики
- Статистична функція
Загальні функції
Ми вже знайомі із загальними функціями, такими як функції cbind (), rbind (), range (), sort (), order (). Кожна з цих функцій має конкретне завдання, бере аргументи для повернення результату. Нижче наведені важливі функції, які потрібно знати
функція diff ()
Якщо ви працюєте над часовими рядами , вам потрібно стаціонарно встановити ряд, взявши їх значення відставання . Стаціонарний процес дозволяє постійно середнє значення, дисперсія і автокорреляция з плином часу. Це в основному покращує прогнозування часового ряду. Це можна легко зробити за допомогою функції diff (). Ми можемо побудувати випадкові дані часових рядів з трендом, а потім використати функцію diff () для стаціонарного ряду. Функція diff () приймає один аргумент, вектор, і повертає відповідну відсталу та повторну різницю.
Примітка : Нам часто потрібно створювати випадкові дані, але для вивчення та порівняння ми хочемо, щоб цифри були однакові на різних машинах. Щоб переконатися, що всі ми генеруємо однакові дані, ми використовуємо функцію set.seed () з довільними значеннями 123. Функція set.seed () генерується за допомогою процесу генератора псевдовипадкових чисел, завдяки якому кожен сучасний комп'ютер має однакову послідовність чисел. Якщо ми не використовуємо функцію set.seed (), усі ми матимемо різну послідовність чисел.
set.seed(123)## Create the datax = rnorm(1000)ts <- cumsum(x)## Stationary the seriediff_ts <- diff(ts)par(mfrow=c(1,2))## Plot the seriesplot(ts,)plot(diff(ts),)
функція length ()
У багатьох випадках ми хочемо знати довжину вектора для обчислення або використовуватись у циклі for. Функція length () підраховує кількість рядків у векторі x. Наступні коди імпортують набір даних про автомобілі та повертають кількість рядків.
Примітка : length () повертає кількість елементів у векторі. Якщо функція передається в матрицю або фрейм даних, повертається кількість стовпців.
dt <- cars## number columnslength(dt)
Вихід:
## [1] 1
## number rowslength(dt[,1])
Вихід:
## [1] 50
Математичні функції
R має масив математичних функцій.
Оператор | Опис |
---|---|
абс (х) | Бере абсолютне значення x |
log (x, base = y) | Бере логарифм x з основою y; якщо база не вказана, повертає натуральний логарифм |
exp (x) | Повертає експоненцію x |
sqrt (x) | Повертає квадратний корінь із x |
факторіал (x) | Повертає факторіал x (x!) |
# sequence of number from 44 to 55 both including incremented by 1x_vector <- seq(45,55, by = 1)#logarithmlog(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
#exponentialexp(x_vector)
#squared rootsqrt(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
#factorialfactorial(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 |
var (x) |
Дисперсія x |
sd (x) |
Стандартне відхилення x |
масштаб (x) |
Стандартні бали (z-бали) x |
квантиль (x) |
Квартилі х |
резюме (x) |
Короткий зміст x: середнє, мінімальне, максимальне тощо ... |
speed <- dt$speedspeed# Mean speed of cars datasetmean(speed)
Вихід:
## [1] 15.4
# Median speed of cars datasetmedian(speed)
Вихід:
## [1] 15
# Variance speed of cars datasetvar(speed)
Вихід:
## [1] 27.95918
# Standard deviation speed of cars datasetsd(speed)
Вихід:
## [1] 5.287644
# Standardize vector speed of cars datasethead(scale(speed), 5)
Вихід:
## [,1]## [1,] -2.155969## [2,] -2.155969## [3,] -1.588609## [4,] -1.588609## [5,] -1.399489
# Quantile speed of cars datasetquantile(speed)
Вихід:
## 0% 25% 50% 75% 100%## 4 12 15 19 25
# Summary speed of cars datasetsummary(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 argumentssome other code}
Примітка : Хороша практика - називати визначену користувачем функцію, відмінну від вбудованої. Це дозволяє уникнути плутанини.
Функція одного аргументу
У наступному фрагменті ми визначаємо просту квадратну функцію. Функція приймає значення і повертає квадрат значення.
square_function<- function(n){# compute the square of integer `n`n^2}# calling the function and passing value 4square_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.
Зверніть увагу, що n, аргумент функції square_function не знаходиться в цьому глобальному середовищі .
Для кожної функції створюється нове середовище. У наведеному вище прикладі функція square_function () створює нове середовище всередині глобального середовища.
Щоб з’ясувати різницю між глобальним та місцевим середовищем , вивчимо наступний приклад
Ця функція приймає значення x як аргумент і додає його до функції y, що визначає зовні та всередині функції
Функція f повертає вихідні дані 15. Це пояснюється тим, що y визначається у глобальному середовищі. Будь-яку змінну, визначену в глобальному середовищі, можна використовувати локально. Змінна y має значення 10 під час усіх викликів функцій і доступна в будь-який час.
Давайте подивимося, що станеться, якщо змінна y визначена всередині функції.
Нам потрібно скинути `y` перед запуском цього коду за допомогою rm r
Вихід також дорівнює 15, коли ми викликаємо f (5), але повертає помилку, коли ми намагаємось надрукувати значення y. Змінна y не знаходиться в глобальному середовищі.
Нарешті, R використовує останнє визначення змінної для передачі всередину функції функції. Давайте розглянемо наступний приклад:
R ігнорує значення y, визначені поза функцією, оскільки ми явно створили ay змінну всередині тіла функції.
Функція декількох аргументів
Ми можемо записати функцію з кількома аргументами. Розглянемо функцію, яка називається "раз". Це пряма функція, яка множить дві змінні.
times <- function(x,y) {x*y}times(2,4)
Вихід:
## [1] 8
Коли слід писати функцію?
Вчений-дослідник даних повинен виконувати багато повторюваних завдань. Здебільшого ми копіюємо та вставляємо фрагменти коду повторно. Наприклад, настійно рекомендується нормалізація змінної перед тим, як ми запускаємо алгоритм машинного навчання. Формула нормалізації змінної така:
Ми вже знаємо, як використовувати функцію min () та max () у R. Ми використовуємо бібліотеку tibble для створення кадру даних. На сьогодні Tibble є найзручнішою функцією для створення набору даних з нуля.
library(tibble)# Create a data framedata_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))
Знаменник: max (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 c1data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))# show the first five valueshead(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 nominatornominator <- x-min(x)# step 2: create the denominatordenominator <- max(x)-min(x)# step 3: divide nominator by denominatornormalize <- nominator/denominator# return the valuereturn(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, наша функція створює набір даних про поїзд, інакше вона створює тестовий набір даних.
Ми можемо продовжувати, як ми робили функцію normalize (). Ми пишемо код так, ніби це був лише одноразовий код, а потім обертаємо все з умовою в тіло, щоб створити функцію.
Крок 1:
Нам потрібно обчислити довжину набору даних. Це робиться за допомогою функції nrow (). Nrow повертає загальну кількість рядків у наборі даних. Ми називаємо змінну довжину.
length<- nrow(airquality)length
Вихід:
## [1] 153
Крок 2:
Множимо довжину на 0,8. Це поверне кількість рядків для вибору. Має бути 153 * 0,8 = 122,4
total_row <- length*0.8total_row
Вихід:
## [1] 122.4
Ми хочемо вибрати 122 рядки серед 153 рядків у наборі даних про повітря. Створюємо список, що містить значення від 1 до total_row. Результат ми зберігаємо у змінній, яка називається split
split <- 1:total_rowsplit[1:5]
Вихід:
## [1] 1 2 3 4 5
split вибирає перші 122 рядки із набору даних. Наприклад, ми можемо бачити, що наша змінна split розділяє значення 1, 2, 3, 4, 5 тощо. Ці значення будуть індексом, коли ми будемо вибирати рядки для повернення.
Крок 3:
Нам потрібно вибрати рядки в наборі даних про якість повітря на основі значень, що зберігаються у змінній split. Це робиться так:
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.8split <- 1:total_rowif (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