Funkcje w programowaniu w języku R z przykładem
⚡ Inteligentne podsumowanie
Funkcje w R to zestaw instrukcji pod jedną nazwą, dzięki czemu powtarzające się zadanie jest uruchamiane po jednym wywołaniu. Wbudowane funkcje pomocnicze do obliczeń matematycznych i statystycznych, funkcje definiowane przez użytkownika, środowisko sco.ping, a argumenty warunkowe omówiono tutaj wraz z przykładami rozwiązań.

Co to jest funkcja w R?
A funkcjonowaćw środowisku programistycznym jest zestawem instrukcji. Programista buduje funkcję, której należy unikać powtarzanie tego samego zadanialub zmniejszyć kompleksowość.
Funkcja powinna być
- napisany w celu wykonania określonego zadania
- może zawierać argumenty lub nie
- zawierać ciało
- może lub nie zwracać jedną lub więcej wartości.
Ogólne podejście do funkcji polega na użyciu części argumentu jako Wejścia, karmić ciało część i na koniec zwróć wydajność. Składnia funkcji jest następująca:
function (arglist) { #Function body }
R ważne funkcje wbudowane
W R jest wiele wbudowanych funkcji. R dopasowuje parametry wejściowe do argumentów funkcji, albo według wartości, albo według pozycji, a następnie wykonuje treść funkcji. Argumenty funkcji mogą mieć wartości domyślne: jeśli nie określisz tych argumentów, R przyjmie wartość domyślną.
Note:
Można zobaczyć kod źródłowy funkcji, uruchamiając samą nazwę funkcji w konsoli.
Typing nazwa funkcji bez nawiasów wyświetla jej źródło, jak pokazuje poniższa konsola.
Zobaczymy trzy grupy funkcji w akcji
- Funkcja ogólna
- Funkcja matematyczna
- Funkcja statystyczna
Funkcje ogólne
Znamy już ogólne funkcje takie jak cbind(), rbind(), range(), sortować()i order(). Każda z tych funkcji ma określone zadanie i przyjmuje argumenty, aby zwrócić wynik. Poniżej przedstawiono ważne funkcje, które należy znać:
funkcja różnicowa().
Jeśli pracujesz nad szereg czasowy, musisz zatrzymać serię, biorąc ich wartości opóźnienia, ZA proces stacjonarny Pozwala na stałą średnią, wariancję i autokorelację w czasie. To przede wszystkim poprawia przewidywanie szeregów czasowych. Można to zrobić za pomocą funkcji diff(). Możemy zbudować losowy szereg czasowy z trendem, a następnie użyć funkcji diff() do stacjonaryzacji szeregu. Funkcja diff() przyjmuje jeden argument, wektor, i zwraca odpowiednią opóźnioną i iterowaną różnicę.
NoteCzęsto musimy tworzyć dane losowe, ale do celów uczenia się i porównywania chcemy, aby liczby były identyczne na wszystkich maszynach. Aby mieć pewność, że wszyscy wygenerujemy te same dane, używamy funkcji set.seed() z dowolnymi wartościami 123. Funkcja set.seed() ustala punkt początkowy generatora liczb pseudolosowych, dzięki czemu każda maszyna generuje tę samą sekwencję. Bez funkcji set.seed() każde wywołanie zwraca inną sekwencję.
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')
Na dwóch poniższych panelach umieszczono oryginalną serię skumulowaną obok serii różnicowej, która teraz oscyluje wokół stałej średniej.
funkcja długość().
W wielu przypadkach chcemy poznać długość wektora do obliczeń lub do użycia w pętli for. Funkcja length() zlicza liczbę wierszy w wektorze x. Poniższe kody importują zbiór danych samochodów i zwracają liczbę wierszy.
Note:length() zwraca liczbę elementów w wektorze. Jeśli funkcja jest przekazywana do matryca lub ramki danych, zwracana jest liczba kolumn.
dt <- cars
## number columns
length(dt)
Wyjście:
## [1] 1
## number rows
length(dt[,1])
Wyjście:
## [1] 50
Funkcje matematyczne
Oprócz ogólnych funkcji pomocniczych R oferuje szereg funkcji matematycznych, które operują element po elemencie wektora.
| OperaTor | OPIS |
|---|---|
| abs (x) | Przyjmuje wartość bezwzględną x |
| log(x,podstawa=y) | Oblicza logarytm z x o podstawie y; jeśli podstawa nie jest określona, zwraca logarytm naturalny |
| exp (x) | Zwraca wykładnik x |
| sqrt (x) | Zwraca pierwiastek kwadratowy z x |
| silnia(x) | Zwraca silnię 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)
Wyjście:
## [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)
Wyjście:
## [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)
Wyjście:
## [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
Funkcje statystyczne
Podczas gdy funkcje matematyczne przekształcają wartości, funkcje statystyczne je podsumowują. Standardowa instalacja R zawiera szeroki zakres funkcji statystycznych. W tym samouczku pokrótce omówimy najważniejsze z nich.
Podstawowe funkcje statystyczne
| OperaTor | OPIS |
|---|---|
| znaczy (x) | Średnia x |
| mediana (x) | Mediana x |
| zmienna(x) | Wariancja x |
| SD(x) | Odchylenie standardowe x |
| skala (x) | Wyniki standardowe (wyniki Z) x |
| kwantyl(x) | Kwartyle x |
| podsumowanie(x) | Podsumowanie x: średnia, min, max itp. |
speed <- dt$speed
speed
# Mean speed of cars dataset
mean(speed)
Wyjście:
## [1] 15.4
# Median speed of cars dataset
median(speed)
Wyjście:
## [1] 15
# Variance speed of cars dataset
var(speed)
Wyjście:
## [1] 27.95918
# Standard deviation speed of cars dataset
sd(speed)
Wyjście:
## [1] 5.287644
# Standardize vector speed of cars dataset
head(scale(speed), 5)
Wyjście:
## [,1] ## [1,] -2.155969 ## [2,] -2.155969 ## [3,] -1.588609 ## [4,] -1.588609 ## [5,] -1.399489
# Quantile speed of cars dataset
quantile(speed)
Wyjście:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset
summary(speed)
Wyjście:
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 4.0 12.0 15.0 15.4 19.0 25.0
Do tego momentu poznaliśmy wiele funkcji wbudowanych w język R.
Note:Uważaj na klasa argumentu, czyli wartość numeryczna, logiczna lub ciąg znaków. Na przykład, jeśli chcemy przekazać wartość ciągu znaków, musimy ująć go w cudzysłów: „ABC”.
Zapisz funkcję w R
Czasami musimy napisać własną funkcję, ponieważ musimy wykonać określone zadanie, a nie ma gotowej funkcji. Funkcja zdefiniowana przez użytkownika obejmuje Nazwa, argumenty oraz ciało.
function.name <- function(arguments) { computations on the arguments some other code }
Note: Dobrą praktyką jest nadawanie funkcji zdefiniowanej przez użytkownika innej nazwy niż funkcji wbudowanej. Pozwala uniknąć zamieszania.
Funkcja z jednym argumentem
W następnym fragmencie definiujemy prostą funkcję kwadratową. Funkcja przyjmuje wartość i zwraca kwadrat wartości.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Code Wyjaśnienie
- Funkcja nosi nazwę Square_function; można to nazwać jakkolwiek chcemy.
- Otrzymuje argument „n”. My nie określono typu zmiennej, aby użytkownik mógł przekazać liczbę całkowitą, wektor lub macierz
- Funkcja pobiera wartość wejściową „n” i zwraca kwadrat wartości wejściowej. Kiedy skończysz korzystać z tej funkcji, możemy ją usunąć za pomocą funkcji rm().
# po utworzeniu funkcji
rm(square_function) square_function
Na konsoli pojawia się komunikat o błędzie:Error: nie znaleziono obiektu 'square_function' informujący, że funkcja nie istnieje.
Środowisko Scoping
W R środowisko jest zbiorem obiektów takich jak funkcje, zmienne, ramki danych, itp.
R otwiera środowisko przy każdym uruchomieniu RStudio.
Dostępne środowisko najwyższego poziomu to globalnego Środowiska, zwanego R_GlobalEnv. I mamy lokalne środowisko.
Możemy wyświetlić zawartość bieżącego środowiska.
ls(environment())
Wydajność
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
Możesz zobaczyć wszystkie zmienne i funkcje utworzone w pliku R_GlobalEnv.
Powyższa lista będzie się różnić w zależności od historycznego kodu wykonywanego w RStudio.
Należy pamiętać, że n, argument funkcji square_function nie znajduje się w tym środowisku globalnym.
Dla każdej funkcji tworzone jest nowe środowisko. W powyższym przykładzie funkcja square_function() tworzy nowe środowisko wewnątrz globalnego Środowiska.
Aby wyjaśnić różnicę między światowy oraz miejscowy środowisko, przeanalizujmy następujący przykład
Funkcje te przyjmują wartość x jako argument i dodają ją do definicji y na zewnątrz i wewnątrz funkcji
Funkcja f zwraca wynik 15. Dzieje się tak, ponieważ y jest zdefiniowane w środowisku globalnym. Lokalnie można używać dowolnej zmiennej zdefiniowanej w środowisku globalnym. Zmienna y podczas wszystkich wywołań funkcji ma wartość 10 i jest dostępna w każdej chwili.
Zobaczmy, co się stanie, jeśli wewnątrz funkcji zdefiniowana zostanie zmienna y.
Musimy usunąć `y` przed uruchomieniem tego kodu za pomocą rm r
Wynik również wynosi 15, gdy wywołujemy f(5), ale zwraca błąd, gdy próbujemy wydrukować wartość y. Zmienna y nie znajduje się w środowisku globalnym.
Na koniec R używa najnowszej definicji zmiennej do przekazania wewnątrz ciała funkcji. Rozważmy następujący przykład:
R ignoruje wartości y zdefiniowane poza funkcją, ponieważ jawnie utworzyliśmy zmienną y wewnątrz treści funkcji.
Funkcja wielu argumentów
Możemy napisać funkcję z więcej niż jednym argumentem. Rozważmy funkcję zwaną „czasami”. Jest to prosta funkcja mnożąca dwie zmienne.
times <- function(x,y) {
x*y
}
times(2,4)
Wyjście:
## [1] 8
Kiedy powinniśmy pisać funkcję?
Analitycy danych muszą wykonywać wiele powtarzalnych zadań. Zazwyczaj kopiujemy i wklejamy fragmenty kodu w sposób powtarzalny. Na przykład, przed uruchomieniem analizy zdecydowanie zaleca się normalizację zmiennej. uczenie maszynowe algorytm. Formuła normalizująca zmienną to:
Wiemy już, jak używać funkcji min() i max() w R. Do tworzenia ramki danych używamy biblioteki tibble. Tibble jest jak dotąd najwygodniejszą funkcją do tworzenia zestawu danych od zera.
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), )
Obliczenie funkcji opisanej powyżej wykonamy w dwóch krokach. W pierwszym kroku utworzymy zmienną o nazwie c1_norm, która będzie skalowaniem c1. W kroku drugim po prostu skopiujemy i wkleimy kod c1_norm, a następnie zamienimy go na c2 i c3.
Szczegóły funkcji z kolumną c1:
Nominator: : ramka_danych$c1 -min(ramka_danych$c1))
Mianownik: max(data_frame$c1)-min(data_frame$c1))
Dlatego możemy je podzielić, aby uzyskać znormalizowaną wartość kolumny c1:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
Możemy stworzyć c1_norm, c2_norm i 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)
Wyjście:
## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991
To działa. Możemy kopiować i wklejać
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
następnie zmień c1_norm na c2_norm i c1 na c2. Robimy to samo, aby utworzyć 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))
Doskonale przeskalowaliśmy zmienne c1, c2 i c3.
Jednak ta metoda jest podatna na błędy. Moglibyśmy skopiować i zapomnieć o zmianie nazwy kolumny po wklejeniu. Dlatego dobrą praktyką jest pisanie funkcji za każdym razem, gdy musimy wkleić ten sam kod więcej niż dwa razy. Możemy przekształcić kod w formułę i wywołać ją w razie potrzeby. Aby napisać własną funkcję, musimy podać:
- Nazwa: normalize.
- liczba argumentów: Potrzebujemy tylko jednego argumentu, czyli kolumny, której używamy w naszych obliczeniach.
- Ciało: to po prostu formuła, którą chcemy zwrócić.
Będziemy krok po kroku tworzyć funkcję normalize.
Krok 1) Tworzymy licznik, który wynosi x – min(x). W R możemy zapisać licznik w zmiennej w następujący sposób:
nominator <- x-min(x)
Krok 2) Obliczamy mianownik: max(x) – min(x). Możemy powtórzyć ideę z kroku 1 i zapisać obliczenia w zmiennej:
denominator <- max(x)-min(x)
Krok 3) Dokonujemy podziału między mianownikiem i mianownikiem.
normalize <- nominator/denominator
Krok 4) Aby zwrócić wartość do funkcji wywołującej, musimy przekazać wartość normalize wewnątrz funkcji return() w celu uzyskania wyniku funkcji.
return(normalize)
Krok 5) Jesteśmy gotowi do użycia funkcji poprzez zawinięcieping wszystko co znajduje się w nawiasie.
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) }
Przetestujmy naszą funkcję ze zmienną c1:
normalize(data_frame$c1)
Działa idealnie. Stworzyliśmy naszą pierwszą funkcję.
Funkcja to bardziej kompleksowy sposób wykonywania powtarzalnego zadania. Możemy użyć formuły normalizującej dla różnych kolumn, jak poniżej:
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)
Chociaż przykład jest prosty, możemy wywnioskować moc formuły. Powyższy kod jest łatwiejszy do odczytania i pozwala uniknąć błędów związanych z wklejaniem kodu.
Funkcje z warunkiem
Funkcja normalize() zawsze robi to samo. Czasami musimy uwzględnić warunki w funkcji, aby kod mógł zwracać różne wyniki.
W zadaniach uczenia maszynowego musimy podzielić zbiór danych pomiędzy zestaw pociągowy i zestaw testowy. Zestaw pociągów pozwala algorytmowi uczyć się na podstawie danych. Aby przetestować wydajność naszego modelu, możemy użyć zestawu testowego do zwrócenia miary wydajności. R nie ma funkcji umożliwiającej utworzenie dwóch zbiorów danych. Możemy napisać własną funkcję, która to zrobi. Nasza funkcja przyjmuje dwa argumenty i nosi nazwę split_data(). Pomysł jest prosty, mnożymy długość zbioru danych (tj. liczbę obserwacji) przez 0.8. Na przykład, jeśli chcemy podzielić zbiór danych 80/20, a nasz zbiór danych zawiera 100 wierszy, to nasza funkcja pomnoży 0.8*100 = 80. 80 wierszy zostanie wybranych jako dane szkoleniowe.
Wykorzystamy zbiór danych o jakości powietrza do przetestowania naszej funkcji zdefiniowanej przez użytkownika. Zbiór danych o jakości powietrza składa się ze 153 wierszy. Możemy to zobaczyć za pomocą poniższego kodu:
nrow(airquality)
Wyjście:
## [1] 153
Postępujemy następująco:
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
Nasza funkcja ma dwa argumenty. Argument train jest parametrem boolowskim. Jeśli jest ustawiony na TRUE, nasza funkcja tworzy zestaw danych train, w przeciwnym razie tworzy zestaw danych testowych.
Możemy postępować tak samo, jak w przypadku funkcji normalize(). Piszemy kod tak, jakby był to kod jednorazowy, a następnie umieszczamy wszystko w ciele funkcji, dodając warunek.
Krok 1:
Musimy obliczyć długość zbioru danych. Robi się to za pomocą funkcji nrow(). Nrow zwraca całkowitą liczbę wierszy w zbiorze danych. Nazywamy zmienną długość.
length<- nrow(airquality) length
Wyjście:
## [1] 153
Krok 2:
Mnożymy długość przez 0.8. Zwróci liczbę wierszy do wybrania. Powinno być 153*0.8 = 122.4
total_row <- length*0.8 total_row
Wyjście:
## [1] 122.4
Chcemy wybrać 122 wiersze spośród 153 wierszy w zestawie danych o jakości powietrza. Tworzymy listę zawierającą wartości od 1 do total_row. Wynik przechowujemy w zmiennej zwanej split
split <- 1:total_row split[1:5]
Wyjście:
## [1] 1 2 3 4 5
split wybiera pierwsze 122 wiersze ze zbioru danych. Na przykład widzimy, że nasza zmienna split gromadzi wartości 1, 2, 3, 4, 5 i tak dalej. Wartości te będą indeksem, gdy wybierzemy wiersze do zwrócenia.
Krok 3:
Musimy wybrać wiersze w zestawie danych o jakości powietrza na podstawie wartości przechowywanych w zmiennej podziału. Odbywa się to w następujący sposób:
train_df <- airquality[split, ] head(train_df)
Wyjście:
##[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
Krok 4:
Możemy utworzyć testowy zbiór danych, korzystając z pozostałych wierszy, 123:153. Odbywa się to za pomocą – przed podziałem.
test_df <- airquality[-split, ] head(test_df)
Wyjście:
##[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
Krok 5:
Możemy stworzyć warunek wewnątrz treści funkcji. Pamiętaj, że mamy ciąg argumentów, który jest domyślnie ustawioną wartością logiczną na TRUE, aby zwrócić zestaw. Aby utworzyć warunek, używamy składni if:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
To wszystko, możemy napisać funkcję. Musimy tylko zmienić jakość powietrza na df, ponieważ chcemy wypróbować naszą funkcję na dowolnej ramka danych, nie tylko jakość powietrza:
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) } }
Wypróbujmy naszą funkcję na zbiorze danych dotyczących jakości powietrza. Powinniśmy mieć jeden zbiór danych ze 122 wierszami i zbiór testowy z 31 wierszami.
train <- split_data(airquality, train = TRUE)
dim(train)
Wyjście:
## [1] 122 6
test <- split_data(airquality, train = FALSE)
dim(test)
Wyjście:
## [1] 31 6






