Co to jest funkcja w języku R?
Funkcja w środowisku programowania, to zestaw instrukcji. Programista tworzy funkcję, aby uniknąć powtarzania tego samego zadania lub zmniejszyć złożoność.
Powinna być funkcja
- napisane w celu wykonania określonego zadania
- może zawierać argumenty lub nie
- zawierać ciało
- może zwracać jedną lub więcej wartości, ale nie musi.
Ogólnym podejściem do funkcji jest użycie argumentu jako danych wejściowych , przekazanie części ciała i na koniec zwrócenie wyniku . Składnia funkcji jest następująca:
function (arglist) {#Function body}
W tym samouczku nauczymy się
- R ważne wbudowane funkcje
- Funkcje ogólne
- Funkcje matematyczne
- Funkcje statystyczne
- Funkcja zapisu w R
- Kiedy powinniśmy napisać funkcję?
- Funkcje z warunkiem
R ważne wbudowane funkcje
Istnieje wiele funkcji wbudowanych w R. R dopasowuje parametry wejściowe do argumentów funkcji według wartości lub 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ą.
Uwaga : Kod źródłowy funkcji można zobaczyć, uruchamiając nazwę samej funkcji w konsoli.
Zobaczymy w akcji trzy grupy funkcji
- Funkcja ogólna
- Funkcja matematyczna
- Funkcja statystyczna
Funkcje ogólne
Znamy już ogólne funkcje, takie jak cbind (), rbind (), range (), sort (), order (). Każda z tych funkcji ma określone zadanie, pobiera argumenty, aby zwrócić dane wyjściowe. Oto ważne funkcje, które należy znać:
diff () funkcja
Jeśli pracujesz nad szeregami czasowymi , musisz unieruchomić serie, biorąc ich wartości opóźnienia . Stacjonarny proces umożliwia ciągłe średniej, wariancji autokorelacja w czasie. Poprawia to głównie przewidywanie szeregu czasowego. Można to łatwo zrobić za pomocą funkcji diff (). Możemy zbudować losowe dane szeregów czasowych z trendem, a następnie użyć funkcji diff () do unieruchomienia szeregu. Funkcja diff () przyjmuje jeden argument, wektor i zwraca odpowiednią opóźnioną i iterowaną różnicę.
Uwaga : Często musimy tworzyć losowe dane, ale w celu uczenia się i porównywania chcemy, aby liczby były identyczne na różnych maszynach. Aby upewnić się, że wszyscy generujemy te same dane, używamy funkcji set.seed () z dowolnymi wartościami 123. Funkcja set.seed () jest generowana w procesie generatora liczb pseudolosowych, który sprawia, że każdy współczesny komputer ma tę samą sekwencję liczb. Jeśli nie użyjemy funkcji set.seed (), wszyscy będziemy mieli inną sekwencję liczb.
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 (), funkcja
W wielu przypadkach chcemy znać długość wektora do obliczeń lub użyć go w pętli for. Funkcja length () zlicza wiersze w wektorze x. Poniższe kody importują zestaw danych samochodów i zwracają liczbę wierszy.
Uwaga : length () zwraca liczbę elementów w wektorze. Jeśli funkcja zostanie przekazana do macierzy lub ramki danych, zwracana jest liczba kolumn.
dt <- cars## number columnslength(dt)
Wynik:
## [1] 1
## number rowslength(dt[,1])
Wynik:
## [1] 50
Funkcje matematyczne
R ma tablicę funkcji matematycznych.
Operator | Opis |
---|---|
abs (x) | Przyjmuje wartość bezwzględną x |
log (x, podstawa = y) | Przyjmuje logarytm z x o podstawie y; jeśli podstawa nie jest określona, zwraca logarytm naturalny |
exp (x) | Zwraca wykładniczą wartość 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 1x_vector <- seq(45,55, by = 1)#logarithmlog(x_vector)
Wynik:
## [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)
Wynik:
## [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)
Wynik:
## [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
Standardowa instalacja R zawiera szeroki zakres funkcji statystycznych. W tym samouczku pokrótce przyjrzymy się najważniejszej funkcji…
Podstawowe funkcje statystyczne
Operator |
Opis |
---|---|
średnia (x) |
Średnia x |
mediana (x) |
Mediana x |
var (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 itd… |
speed <- dt$speedspeed# Mean speed of cars datasetmean(speed)
Wynik:
## [1] 15.4
# Median speed of cars datasetmedian(speed)
Wynik:
## [1] 15
# Variance speed of cars datasetvar(speed)
Wynik:
## [1] 27.95918
# Standard deviation speed of cars datasetsd(speed)
Wynik:
## [1] 5.287644
# Standardize vector speed of cars datasethead(scale(speed), 5)
Wynik:
## [,1]## [1,] -2.155969## [2,] -2.155969## [3,] -1.588609## [4,] -1.588609## [5,] -1.399489
# Quantile speed of cars datasetquantile(speed)
Wynik:
## 0% 25% 50% 75% 100%## 4 12 15 19 25
# Summary speed of cars datasetsummary(speed)
Wynik:
## Min. 1st Qu. Median Mean 3rd Qu. Max.## 4.0 12.0 15.0 15.4 19.0 25.0
Do tego momentu nauczyliśmy się wielu wbudowanych funkcji R.
Uwaga : Uważaj na klasę argumentu, tj. Numeryczną, logiczną lub łańcuchową. Na przykład, jeśli musimy przekazać wartość ciągu, musimy umieścić ciąg w cudzysłowie: „ABC”.
Funkcja zapisu w R
Czasami musimy napisać własną funkcję, ponieważ musimy wykonać określone zadanie i nie istnieje gotowa funkcja. Funkcja zdefiniowana przez użytkownika zawiera nazwę , argumenty i treść .
function.name <- function(arguments){computations on the argumentssome other code}
Uwaga : dobrą praktyką jest nazwanie funkcji zdefiniowanej przez użytkownika inaczej niż funkcja wbudowana. Pozwala uniknąć nieporozumień.
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 4square_function(4)
Objaśnienie kodu:
- Funkcja nazywa się funkcja_kwadratowa; można to nazwać, jak chcemy.
- Otrzymuje argument „n”. My nie określił typ zmiennej, dzięki czemu użytkownik może przejść liczbę całkowitą, wektor lub macierz
- Funkcja przyjmuje dane wejściowe „n” i zwraca kwadrat z wejścia.
Po zakończeniu korzystania z funkcji możemy ją usunąć za pomocą funkcji rm ().
# po utworzeniu funkcji
rm(square_function)square_function
Na konsoli widzimy komunikat o błędzie: Błąd: nie znaleziono obiektu „funkcja_kwadratowa”, co oznacza, że funkcja nie istnieje.
Zakres środowiska
W R środowisko to zbiór obiektów, takich jak funkcje, zmienne, ramki danych itp.
R otwiera środowisko za każdym razem, gdy pojawia się monit Rstudio.
Dostępnym środowiskiem najwyższego poziomu jest środowisko globalne o nazwie R_GlobalEnv. Mamy też lokalne środowisko.
Możemy wymienić zawartość obecnego środowiska.
ls(environment())
Wynik
## [1] "diff_ts" "dt" "speed" "square_function"## [5] "ts" "x" "x_vector"
Możesz zobaczyć wszystkie zmienne i funkcje utworzone w R_GlobalEnv.
Powyższa lista będzie się różnić w zależności od historycznego kodu wykonywanego w R Studio.
Zauważ, że n, argument funkcji square_function nie znajduje się w tym globalnym środowisku .
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 środowiskiem globalnym a lokalnym , przeanalizujmy następujący przykład
Te funkcje przyjmują wartość x jako argument i dodają ją do y definiującej na zewnątrz i wewnątrz funkcji
Funkcja f zwraca wynik 15. Dzieje się tak, ponieważ y jest zdefiniowane w środowisku globalnym. Każda zmienna zdefiniowana w środowisku globalnym może być używana lokalnie. Zmienna y ma wartość 10 podczas wszystkich wywołań funkcji i jest dostępna w dowolnym momencie.
Zobaczmy, co się stanie, jeśli zmienna y zostanie zdefiniowana wewnątrz funkcji.
Musimy porzucić „y” przed uruchomieniem tego kodu przy użyciu rm r
Wynik jest również równy 15, gdy wywołujemy f (5), ale zwraca błąd, gdy próbujemy wydrukować wartość y. Zmienna y nie znajduje się w środowisku globalnym.
Wreszcie, R używa najnowszej definicji zmiennej, aby przekazać ją do treści funkcji. Rozważmy następujący przykład:
R ignoruje wartości y zdefiniowane poza funkcją, ponieważ jawnie utworzyliśmy zmienną ay w treści funkcji.
Funkcja wielu argumentów
Możemy napisać funkcję z więcej niż jednym argumentem. Rozważmy funkcję o nazwie „czasy”. Jest to prosta funkcja mnożąca dwie zmienne.
times <- function(x,y) {x*y}times(2,4)
Wynik:
## [1] 8
Kiedy powinniśmy napisać funkcję?
Naukowcy zajmujący się danymi muszą wykonywać wiele powtarzalnych zadań. W większości przypadków powtarzamy kopiowanie i wklejanie fragmentów kodu. Na przykład normalizacja zmiennej jest wysoce zalecana przed uruchomieniem algorytmu uczenia maszynowego. Wzór na normalizację zmiennej 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 podstaw.
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),)
Wykonamy dwa kroki, aby obliczyć funkcję opisaną powyżej. W pierwszym kroku utworzymy zmienną o nazwie c1_norm, która jest przeskalowaniem c1. W kroku drugim po prostu kopiujemy i wklejamy kod c1_norm i zmieniamy za pomocą c2 i c3.
Szczegóły funkcji z kolumną c1:
Nominator:: data_frame $ c1 -min (data_frame $ c1))
Mianownik: max (ramka_danych $ c1) -min (ramka_danych $ 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 utworzyć c1_norm, c2_norm i 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)
Wynik:
## [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 pomyłkę. Moglibyśmy skopiować i zapomnieć o zmianie nazwy kolumny po wklejeniu. Dlatego dobrą praktyką jest pisanie funkcji za każdym razem, gdy trzeba wkleić ten sam kod więcej niż dwa razy. Możemy przekształcić kod w formułę i wywoływać ją, kiedy jest to potrzebne. Aby napisać własną funkcję, musimy podać:
- Nazwa: normalizuj.
- liczba argumentów: Potrzebujemy tylko jednego argumentu, czyli kolumny, której używamy w naszych obliczeniach.
- Ciało: to jest po prostu formuła, którą chcemy zwrócić.
Będziemy postępować krok po kroku, aby utworzyć normalizację funkcji.
Krok 1) Tworzymy nominator , którym jest. W R możemy przechowywać licznik w zmiennej takiej jak ta:
nominator <- x-min(x)
Krok 2) obliczamy mianownik . Możemy powtórzyć ideę z kroku 1 i zapisać obliczenia w zmiennej:
denominator <- max(x)-min(x)
Krok 3) Dokonujemy podziału na licznik i mianownik.
normalize <- nominator/denominator
Krok 4) Aby zwrócić wartość do funkcji wywołującej, musimy przekazać normalizację wewnątrz funkcji return (), aby uzyskać dane wyjściowe funkcji.
return(normalize)
Krok 5) Jesteśmy gotowi do użycia funkcji, opakowując wszystko w nawias.
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)}
Przetestujmy naszą funkcję ze zmienną c1:
normalize(data_frame$c1)
Działa doskonale. Stworzyliśmy naszą pierwszą funkcję.
Funkcje to bardziej wszechstronny sposób wykonywania powtarzalnych zadań. Możemy użyć formuły normalizacji w różnych kolumnach, 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ć siłę formuły. Powyższy kod jest łatwiejszy do odczytania, a zwłaszcza pozwala uniknąć błędów podczas wklejania kodów.
Funkcje z warunkiem
Czasami musimy uwzględnić warunki w funkcji, aby umożliwić kodowi zwracanie różnych wyników.
W zadaniach uczenia maszynowego musimy podzielić zestaw danych między zestaw pociągów 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 tworzenia dwóch zestawów danych. Możemy w tym celu napisać własną funkcję. Nasza funkcja przyjmuje dwa argumenty i nazywa się split_data (). Idea jest prosta, 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, wówczas nasza funkcja pomnoży 0,8 * 100 = 80. 80 wierszy zostanie wybranych jako dane szkoleniowe.
Użyjemy zestawu danych jakości powietrza, aby przetestować naszą funkcję zdefiniowaną przez użytkownika. Zbiór danych jakości powietrza ma 153 wiersze. Możemy to zobaczyć za pomocą poniższego kodu:
nrow(airquality)
Wynik:
## [1] 153
Będziemy postępować 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. Pociąg argumentów jest parametrem logicznym. Jeśli jest ustawiona na TRUE, nasza funkcja tworzy zestaw danych pociągu, w przeciwnym razie tworzy testowy zestaw danych.
Możemy postępować tak, jak zrobiliśmy z funkcją normalize (). Piszemy kod tak, jakby był to tylko jednorazowy kod, a następnie zawijamy wszystko z warunkiem do treści, aby utworzyć funkcję.
Krok 1:
Musimy obliczyć długość zbioru danych. Odbywa się to za pomocą funkcji nrow (). Nrow zwraca całkowitą liczbę wierszy w zbiorze danych. Nazywamy zmienną długością.
length<- nrow(airquality)length
Wynik:
## [1] 153
Krok 2:
Mnożymy długość przez 0,8. Zwróci liczbę wierszy do wybrania. Powinien wynosić 153 * 0,8 = 122,4
total_row <- length*0.8total_row
Wynik:
## [1] 122.4
Chcemy wybrać 122 wiersze spośród 153 wierszy w zestawie danych dotyczących jakości powietrza. Tworzymy listę zawierającą wartości od 1 do total_row. Wynik przechowujemy w zmiennej o nazwie split
split <- 1:total_rowsplit[1:5]
Wynik:
## [1] 1 2 3 4 5
split wybiera pierwsze 122 wiersze ze zbioru danych. Na przykład widzimy, że nasza zmienna split zbiera wartość 1, 2, 3, 4, 5 i tak dalej. Te wartości będą indeksem, gdy będziemy wybierać 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. Robi się to w następujący sposób:
train_df <- airquality[split, ]head(train_df)
Wynik:
##[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 zestaw danych, używając pozostałych wierszy 123: 153. Odbywa się to za pomocą - przed splitem.
test_df <- airquality[-split, ]head(test_df)
Wynik:
##[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 argument pociąg, który jest wartością logiczną ustawioną na PRAWDA domyślnie, aby zwrócić zestaw pociągu. 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 jest to, możemy napisać funkcję. Musimy tylko zmienić jakość powietrza na df, ponieważ chcemy wypróbować naszą funkcję na dowolnej ramce danych, nie tylko jakości powietrza:
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)}}
Wypróbujmy naszą funkcję na zbiorze danych jakości powietrza. powinniśmy mieć jeden zestaw składający się ze 122 rzędów i zestaw testowy z 31 rzędami.
train <- split_data(airquality, train = TRUE)dim(train)
Wynik:
## [1] 122 6
test <- split_data(airquality, train = FALSE)dim(test)
Wynik:
## [1] 31 6