Funktioner i R-programmering (med exempel)

Innehållsförteckning:

Anonim

Vad är en funktion i R?

En funktion i en programmeringsmiljö är en uppsättning instruktioner. En programmerare bygger en funktion för att undvika att upprepa samma uppgift eller minska komplexiteten.

En funktion ska vara

  • skrivna för att utföra en specificerad a uppgifter
  • kan innehålla argument eller inte
  • innehålla en kropp
  • kan returnera ett eller flera värden.

Ett allmänt tillvägagångssätt för en funktion är att använda argumentdelen som ingångar , mata kroppsdelen och slutligen returnera en utgång . Syntaxen för en funktion är följande:

function (arglist) {#Function body}

I den här handledningen lär vi oss

  • R viktiga inbyggda funktioner
  • Allmänna funktioner
  • Matematiska funktioner
  • Statistiska funktioner
  • Skrivfunktion i R
  • När ska vi skriva funktion?
  • Funktioner med tillstånd

R viktiga inbyggda funktioner

Det finns många inbyggda funktioner i R. R matchar dina ingångsparametrar med dess funktionsargument, antingen efter värde eller efter position, och kör sedan funktionens kropp. Funktionsargument kan ha standardvärden: om du inte anger dessa argument tar R standardvärdet.

Obs! Det är möjligt att se källkoden för en funktion genom att köra namnet på själva funktionen i konsolen.

Vi kommer att se tre funktionsgrupper i aktion

  • Allmän funktion
  • Matematikfunktion
  • Statistisk funktion

Allmänna funktioner

Vi känner redan till allmänna funktioner som cbind (), rbind (), range (), sort (), order () -funktioner. Var och en av dessa funktioner har en specifik uppgift, tar argument för att returnera en utdata. Följande är viktiga funktioner som man måste veta

diff () -funktion

Om du arbetar med tidsserier måste du stilla serien genom att ta deras fördröjningsvärden . En stationär process tillåter konstant medelvärde, varians och autokorrelation över tiden. Detta förbättrar främst förutsägelsen för en tidsserie. Det kan enkelt göras med funktionen diff (). Vi kan bygga en slumpmässig tidsseriedata med en trend och sedan använda funktionen diff () för att stilla serien. Funktionen diff () accepterar ett argument, en vektor, och returnerar lämplig lagged och iterated skillnad.

Obs : Vi behöver ofta skapa slumpmässiga data, men för inlärning och jämförelse vill vi att siffrorna ska vara identiska över maskiner. För att säkerställa att vi alla genererar samma data använder vi funktionen set.seed () med godtyckliga värden på 123. Funktionen set.seed () genereras genom en pseudorandom-talgenerator som gör att alla moderna datorer har samma sekvens av siffror. Om vi ​​inte använder set.seed () -funktionen har vi alla olika sekvenser av siffror.

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),)

längd () -funktion

I många fall vill vi veta längden på en vektor för beräkning eller att användas i en for-loop. Funktionen längd () räknar antalet rader i vektorn x. Följande koder importerar bilens dataset och returnerar antalet rader.

Obs : längd () returnerar antalet element i en vektor. Om funktionen skickas till en matris eller en dataram returneras antalet kolumner.

dt <- cars## number columnslength(dt)

Produktion:

## [1] 1
## number rowslength(dt[,1])

Produktion:

## [1] 50

Matematiska funktioner

R har en rad matematiska funktioner.

Operatör Beskrivning
abs (x) Tar det absoluta värdet av x
logg (x, bas = y) Tar logaritmen av x med bas y; om bas inte anges, returnerar den naturliga logaritmen
exp (x) Returnerar exponentialen för x
sqrt (x) Returnerar kvadratroten av x
faktoria (x) Returnerar faktorn för x (x!)
# sequence of number from 44 to 55 both including incremented by 1x_vector <- seq(45,55, by = 1)#logarithmlog(x_vector)

Produktion:

## [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)

Produktion:

## [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)

Produktion:

## [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

Statistiska funktioner

R-standardinstallationen innehåller ett brett spektrum av statistiska funktioner. I denna handledning tittar vi kort på den viktigaste funktionen ...

Grundläggande statistikfunktioner

Operatör

Beskrivning

medelvärde (x)

Medelvärde för x

median (x)

Median av x

var (x)

Varians av x

sd (x)

Standardavvikelse på x

skala (x)

Standardpoäng (z-poäng) på x

kvantil (x)

Kvartilerna av x

sammanfattning (x)

Sammanfattning av x: medelvärde, min, max etc ...

speed <- dt$speedspeed# Mean speed of cars datasetmean(speed)

Produktion:

## [1] 15.4
# Median speed of cars datasetmedian(speed)

Produktion:

## [1] 15
# Variance speed of cars datasetvar(speed)

Produktion:

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

Produktion:

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

Produktion:

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

Produktion:

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

Produktion:

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

Fram till denna tid har vi lärt oss många R-inbyggda funktioner.

Obs! Var försiktig med argumentets klass, dvs. numerisk, boolesk eller sträng. Till exempel, om vi behöver skicka ett strängvärde, måste vi bifoga strängen i citattecken: "ABC".

Skrivfunktion i R

Vid vissa tillfällen behöver vi skriva vår egen funktion eftersom vi måste utföra en viss uppgift och ingen färdig funktion finns. En användardefinierad funktion innefattar ett namn , argument och en kropp .

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

Obs! En god praxis är att namnge en användardefinierad funktion som skiljer sig från en inbyggd funktion. Det undviker förvirring.

En argumentfunktion

I nästa utdrag definierar vi en enkel fyrkantig funktion. Funktionen accepterar ett värde och returnerar kvadraten för värdet.

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

Kodförklaring:

  • Funktionen heter square_function; det kan kallas vad vi vill.
  • Den får ett argument "n". Vi specificerade inte typen av variabel så att användaren kan skicka ett heltal, en vektor eller en matris
  • Funktionen tar inmatningen "n" och returnerar kvadraten på ingången.

    När du är klar med funktionen kan vi ta bort den med funktionen rm ().

# efter att du skapat funktionen

rm(square_function)square_function

På konsolen kan vi se ett felmeddelande: Fel: objektet 'kvadratfunktion' hittades inte om att funktionen inte existerar.

Miljöomfattning

I R är miljön en samling objekt som funktioner, variabler, dataram etc.

R öppnar en miljö varje gång Rstudio uppmanas.

Den bästa miljö som finns är den globala miljön , kallad R_GlobalEnv. Och vi har den lokala miljön.

Vi kan lista innehållet i den aktuella miljön.

ls(environment())

Produktion

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

Du kan se alla variabler och funktioner som skapats i R_GlobalEnv.

Listan ovan kommer att variera för dig baserat på den historiska koden du kör i R Studio.

Observera att n, argumentet för funktionen square_function inte finns i denna globala miljö .

En ny miljö skapas för varje funktion. I exemplet ovan skapar funktionen square_function () en ny miljö inuti den globala miljön.

För att klargöra skillnaden mellan global och lokal miljö , låt oss studera följande exempel

Dessa funktioner tar ett värde x som ett argument och lägger till det till y definiera utanför och inuti funktionen

Funktionen f returnerar utdata 15. Detta beror på att y definieras i den globala miljön. Alla variabler som definieras i den globala miljön kan användas lokalt. Variabeln y har värdet 10 under alla funktionssamtal och är tillgänglig när som helst.

Låt oss se vad som händer om variabeln y definieras inuti funktionen.

Vi måste släppa 'y' innan du kör den här koden med rm r

Utgången är också 15 när vi kallar f (5) men returnerar ett fel när vi försöker skriva ut värdet y. Variabeln y finns inte i den globala miljön.

Slutligen använder R den senaste variabeldefinitionen för att passera inuti kroppen för en funktion. Låt oss överväga följande exempel:

R ignorerar y-värdena som definieras utanför funktionen eftersom vi uttryckligen skapade en a-variabel inuti funktionens kropp.

Flera argument fungerar

Vi kan skriva en funktion med mer än ett argument. Tänk på funktionen som kallas "tider". Det är en enkel funktion som multiplicerar två variabler.

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

Produktion:

## [1] 8

När ska vi skriva funktion?

Dataforskare måste göra många repetitiva uppgifter. För det mesta kopierar och klistrar vi bitar av kod upprepade gånger. Till exempel rekommenderas normalisering av en variabel innan vi kör en maskininlärningsalgoritm. Formeln för att normalisera en variabel är:

Vi vet redan hur man använder min () och max () -funktionen i R. Vi använder tibble-biblioteket för att skapa dataramen. Tibble är hittills den mest praktiska funktionen för att skapa en datamängd från grunden.

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),)

Vi fortsätter i två steg för att beräkna funktionen som beskrivs ovan. I det första steget skapar vi en variabel som heter c1_norm som är omskalning av c1. I steg två kopierar och klistrar vi bara in koden för c1_norm och ändrar med c2 och c3.

Detalj av funktionen med kolumnen c1:

Nominator:: data_frame $ c1 -min (data_frame $ c1))

Nämnar: max (data_frame $ c1) -min (data_frame $ c1))

Därför kan vi dela dem för att få det normaliserade värdet för kolumn c1:

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

Vi kan skapa c1_norm, c2_norm och 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)

Produktion:

## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991

Det fungerar. Vi kan kopiera och klistra in

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

ändra sedan c1_norm till c2_norm och c1 till c2. Vi gör detsamma för att skapa 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))

Vi har omskalat variablerna c1, c2 och c3 perfekt.

Men den här metoden är benägen för misstag. Vi kan kopiera och glömma att ändra kolumnnamnet efter att vi har klistrat in. Därför är det bra att skriva en funktion varje gång du behöver klistra in samma kod mer än två gånger. Vi kan ordna om koden i en formel och ringa den när den behövs. För att skriva vår egen funktion måste vi ge:

  • Namn: normalisera.
  • antalet argument: Vi behöver bara ett argument, vilket är den kolumn vi använder i vår beräkning.
  • Kroppen: detta är helt enkelt den formel vi vill returnera.

Vi fortsätter steg för steg för att skapa funktionen normalisera.

Steg 1) Vi skapar nominatorn , vilket är. I R kan vi lagra nominatorn i en variabel så här:

nominator <- x-min(x)

Steg 2) Vi beräkna nämnaren: . Vi kan replikera idén med steg 1 och lagra beräkningen i en variabel:

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

Steg 3) Vi utför uppdelningen mellan nominator och nämnare.

normalize <- nominator/denominator

Steg 4) För att återställa värdet till anropsfunktionen måste vi passera normalisera inuti retur () för att få utdata från funktionen.

return(normalize)

Steg 5) Vi är redo att använda funktionen genom att slå in allt i fästet.

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)}

Låt oss testa vår funktion med variabeln c1:

normalize(data_frame$c1)

Det fungerar perfekt. Vi skapade vår första funktion.

Funktioner är ett mer omfattande sätt att utföra en upprepad uppgift. Vi kan använda normaliseringsformeln över olika kolumner, som nedan:

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)

Även om exemplet är enkelt, kan vi dra slutsatsen om en formel. Ovanstående kod är lättare att läsa och undviker särskilt fel när du klistrar in koder.

Funktioner med tillstånd

Ibland måste vi inkludera villkor i en funktion för att låta koden returnera olika utgångar.

I maskininlärningsuppgifter måste vi dela datauppsättningen mellan en tåguppsättning och en testuppsättning. Tågset gör att algoritmen kan lära av data. För att testa prestandan för vår modell kan vi använda testuppsättningen för att returnera prestandamåttet. R har ingen funktion för att skapa två datamängder. Vi kan skriva vår egen funktion för att göra det. Vår funktion tar två argument och kallas split_data (). Idén bakom är enkel, vi multiplicerar datamängden (dvs. antalet observationer) med 0,8. Om vi ​​till exempel vill dela dataset 80/20, och vår dataset innehåller 100 rader, kommer vår funktion att multiplicera 0,8 * 100 = 80. 80 rader kommer att väljas för att bli vår träningsdata.

Vi kommer att använda luftkvalitetsdatasetet för att testa vår användardefinierade funktion. Luftkvalitetsdatasetet har 153 rader. Vi kan se det med koden nedan:

nrow(airquality)

Produktion:

## [1] 153 

Vi fortsätter enligt följande:

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

Vår funktion har två argument. Argumenten tåg är en boolesk parameter. Om den är inställd på SANT skapar vår funktion tågdatasetet, annars skapar det testdatasetet.

Vi kan fortsätta som vi gjorde vi normalisera () funktionen. Vi skriver koden som om det bara var en engångskod och slår sedan in allt med villkoret i kroppen för att skapa funktionen.

Steg 1:

Vi måste beräkna datamängden. Detta görs med funktionen nrow (). Nrow returnerar det totala antalet rader i datasetet. Vi kallar variabel längd.

length<- nrow(airquality)length

Produktion:

## [1] 153

Steg 2:

Vi multiplicerar längden med 0,8. Antalet rader som ska väljas returneras. Det ska vara 153 * 0,8 = 122,4

total_row <- length*0.8total_row

Produktion:

## [1] 122.4

Vi vill välja 122 rader bland de 153 raderna i luftkvalitetsdatauppsättningen. Vi skapar en lista som innehåller värden från 1 till total_row. Vi lagrar resultatet i variabeln som heter split

split <- 1:total_rowsplit[1:5] 

Produktion:

## [1] 1 2 3 4 5

split väljer de första 122 raderna från datasetet. Till exempel kan vi se att vår variabla split samlar värdet 1, 2, 3, 4, 5 och så vidare. Dessa värden kommer att vara index när vi väljer de rader som ska returneras.

Steg 3:

Vi måste välja raderna i luftkvalitetsdataset baserat på värdena som lagras i delad variabel. Detta görs så här:

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

Produktion:

##[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

Steg 4:

Vi kan skapa testdatan genom att använda de återstående raderna, 123: 153. Detta görs genom att använda - framför split.

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

Produktion:

##[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

Steg 5:

Vi kan skapa tillståndet inne i funktionens kropp. Kom ihåg att vi har ett argument tåg som är en boolesk inställning på SANT som standard för att returnera tågset. För att skapa villkoret använder vi syntaxen if:

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

Det här är det, vi kan skriva funktionen. Vi behöver bara ändra airquality till df eftersom vi vill prova vår funktion till vilken dataram som helst, inte bara airquality:

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)}}

Låt oss prova vår funktion i luftkvalitetsdatasetet. vi borde ha en tåguppsättning med 122 rader och en testuppsättning med 31 rader.

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

Produktion:

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

Produktion:

## [1] 31 6