Функции в програмирането на R (с пример)

Съдържание:

Anonim

Какво е функция в 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) Приема абсолютната стойност на x
log (x, основа = y) Взема логаритъма на x с основа y; ако базата не е посочена, връща естествения логаритъм
опит (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)

Медиана на х

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)

Обяснение на кода:

  • Функцията се нарича квадратна_функция; може да се нарече каквото искаме.
  • Той получава аргумент "n". Не посочихме типа променлива, така че потребителят да може да предаде цяло число, вектор или матрица
  • Функцията взема входа "n" и връща квадрата на входа.

    Когато приключите с използването на функцията, можем да я премахнем с функцията rm ().

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

rm(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, нашата функция създава набор от данни за влака, в противен случай тя създава тестовия набор от данни.

Можем да продължим, както направихме, функцията нормализиране (). Пишем кода, сякаш е само еднократен код и след това обвиваме всичко с условието в тялото, за да създадем функцията.

Етап 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