Funktioner i R-programmering med exempel
Vad รคr en funktion i R?
A fungera, i en programmeringsmiljรถ, รคr en uppsรคttning instruktioner. En programmerare bygger en funktion fรถr att undvika upprepar samma uppgift, eller minska komplexitet.
En funktion bรถr vara
- skriven fรถr att utfรถra vissa uppgifter
- kan innehรฅlla argument eller inte
- innehรฅlla en kropp
- kan eller kanske inte returnerar ett eller flera vรคrden.
En allmรคn instรคllning till en funktion รคr att anvรคnda argumentdelen som ingรฅngar, mata kropp del och slutligen tillbaka en produktion. Syntaxen fรถr en funktion รคr fรถljande:
function (arglist) {
#Function body
}
R viktiga inbyggda funktioner
Det finns mรฅnga inbyggda funktioner i R. R matchar dina indataparametrar med dess funktionsargument, antingen efter vรคrde eller position, och kรถr sedan funktionskroppen. Funktionsargument kan ha standardvรคrden: om du inte anger dessa argument kommer R att ta standardvรคrdet.
Anmรคrkningar:
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 grupper av funktioner i aktion
- Allmรคn funktion
- Matematik funktion
- Statistisk funktion
Allmรคnna funktioner
Vi รคr redan bekanta med 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 man mรฅste kรคnna till
diff() funktion
Om du jobbar pรฅ tidsfรถljder, 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 tid. Detta fรถrbรคttrar frรคmst fรถrutsรคgelsen av 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 stationรคra serien. Funktionen diff() accepterar ett argument, en vektor, och returnerar lรคmplig fรถrdrรถjd och itererad skillnad.
Anmรคrkningar: Vi behรถver ofta skapa slumpmรคssiga data, men fรถr inlรคrning och jรคmfรถrelse vill vi att siffrorna ska vara identiska pรฅ alla 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 processen med pseudoslumptalsgenerator som gรถr att alla moderna datorer har samma sekvens av siffror. Om vi โโinte anvรคnder funktionen set.seed() kommer vi alla att ha olika talfรถljd.
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')
length() funktion
I mรฅnga fall vill vi veta lรคngd av en vektor fรถr berรคkning eller fรถr att anvรคndas i en for-loop. Funktionen length() rรคknar antalet rader i vektorn x. Fรถljande koder importerar bilens datauppsรคttning och returnerar antalet rader.
Anmรคrkningar: length() returnerar antalet element i en vektor. Om funktionen skickas in i en matris eller en dataram returneras antalet kolumner.
dt <- cars ## number columns length(dt)
Produktion:
## [1] 1
## number rows length(dt[,1])
Produktion:
## [1] 50
Matematiska funktioner
R har en rad matematiska funktioner.
| Operator | BESKRIVNING |
|---|---|
| abs (x) | Tar det absoluta vรคrdet av x |
| log(x,bas=y) | Tar logaritmen av x med basen y; om bas inte anges, returnerar den naturliga logaritmen |
| exp(x) | Returnerar exponentialen fรถr x |
| sqrt (x) | Returnerar kvadratroten av x |
| factorial(x) | Returnerar faktorvรคrdet av 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)
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
#exponential exp(x_vector)
#squared root sqrt(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
#factorial factorial(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 standardinstallation innehรฅller ett stort antal statistiska funktioner. I den hรคr handledningen kommer vi kort att titta pรฅ den viktigaste funktionen..
Grundlรคggande statistikfunktioner
| Operator | BESKRIVNING |
|---|---|
| medelvรคrde(x) | Medelvรคrde av x |
| median(x) | Median av x |
| var(x) | Varians av x |
| sd(x) | Standardavvikelse fรถr x |
| skala (x) | Standardpoรคng (z-poรคng) fรถr x |
| kvantil (x) | Kvartilerna fรถr x |
| sammanfattning(x) | Sammanfattning av x: medelvรคrde, min, max osv. |
speed <- dt$speed speed # Mean speed of cars dataset mean(speed)
Produktion:
## [1] 15.4
# Median speed of cars dataset median(speed)
Produktion:
## [1] 15
# Variance speed of cars dataset var(speed)
Produktion:
## [1] 27.95918
# Standard deviation speed of cars dataset sd(speed)
Produktion:
## [1] 5.287644
# Standardize vector speed of cars dataset head(scale(speed), 5)
Produktion:
## [,1] ## [1,] -2.155969 ## [2,] -2.155969 ## [3,] -1.588609 ## [4,] -1.588609 ## [5,] -1.399489
# Quantile speed of cars dataset quantile(speed)
Produktion:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset summary(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 punkt har vi lรคrt oss mรฅnga inbyggda R-funktioner.
Anmรคrkningar: Var fรถrsiktig med argumentets klass, dvs numerisk, boolesk eller strรคng. Om vi โโtill exempel behรถver skicka ett strรคngvรคrde mรฅste vi omge strรคngen inom 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 existerar. En anvรคndardefinierad funktion involverar en namn, argument och en kropp.
function.name <- function(arguments)
{
computations on the arguments
some other code
}
Anmรคrkningar: En bra 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 kvadratisk funktion. Funktionen accepterar ett vรคrde och returnerar kvadraten pรฅ vรคrdet.
square_function<- function(n)
{
# compute the square of integer `n`
n^2
}
# calling the function and passing value 4
square_function(4)
Code Fรถrklaring
- Funktionen heter square_function; det kan kallas vad vi vill.
- Den fรฅr argumentet "n". Vi angav inte typen av variabel sรฅ att anvรคndaren kan skicka ett heltal, en vektor eller en matris
- Funktionen tar ingรฅngen "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 'square_function' hittades inte som talar om att funktionen inte existerar.
Miljรถ Scoping
I R, den miljรถ รคr en samling av objekt som funktioner, variabler, dataram, etc.
R รถppnar en miljรถ varje gรฅng Rstudio uppmanas.
Den tillgรคngliga toppnivรฅmiljรถn รคr global miljรถ, kallad R_GlobalEnv. Och vi har lokal miljรถ.
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 รคr inte i denna globala miljรถ.
A ny miljรถ skapas fรถr varje funktion. I exemplet ovan skapar funktionen square_function() en ny miljรถ i 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 utgรฅngen 15. Detta beror pรฅ att y definieras i den globala miljรถn. Vilken variabel som helst som definieras i den globala miljรถn kan anvรคndas lokalt. Variabeln y har vรคrdet 10 under alla funktionsanrop och รคr tillgรคnglig nรคr som helst.
Lรฅt oss se vad som hรคnder om variabeln y รคr definierad inuti funktionen.
Vi mรฅste slรคppa "y" innan vi kรถr den hรคr koden med rm r
Utdata รคr ocksรฅ 15 nรคr vi anropar 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 in i kroppen av en funktion. Lรฅt oss รถvervรคga fรถljande exempel:
R ignorerar y-vรคrdena som definierats utanfรถr funktionen eftersom vi uttryckligen skapade en ay-variabel inuti funktionens kropp.
Multi argument funktion
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 behรถver gรถra mรฅnga repetitiva uppgifter. Fรถr det mesta kopierar och klistrar vi in โโbitar av kod upprepade gรฅnger. Normalisering av en variabel rekommenderas till exempel starkt innan vi kรถr en maskininlรคrning algoritm. Formeln fรถr att normalisera en variabel รคr:
Vi vet redan hur man anvรคnder funktionen min() och max() i R. Vi anvรคnder tibble-biblioteket fรถr att skapa dataramen. Tibble รคr hittills den mest bekvรคma funktionen fรถr att skapa en datamรคngd frรฅn grunden.
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), )
Vi kommer att gรฅ vidare i tvรฅ steg fรถr att berรคkna funktionen som beskrivs ovan. I det fรถrsta steget kommer vi att skapa en variabel som heter c1_norm som รคr omskalningen av c1. I steg tvรฅ kopierar vi bara och klistrar 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รคmnare: max(data_frame$c1)-min(data_frame$c1))
Dรคrfรถr kan vi dela dem fรถr att fรฅ det normaliserade vรคrdet av 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 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)
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 samma sak 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 skalade om variablerna c1, c2 och c3 perfekt.
Denna metod รคr dock benรคgen att misstag. Vi kan kopiera och glรถmma att รคndra kolumnnamnet efter att ha klistrat in. Dรคrfรถr รคr en bra praxis att skriva en funktion varje gรฅng du behรถver klistra in samma kod mer รคn tvรฅ gรฅnger. Vi kan ordna om koden till en formel och kalla den nรคr det 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 formeln vi vill returnera.
Vi kommer att gรฅ vidare steg fรถr steg fรถr att skapa funktionen normalisera.
Steg 1) Vi skapar nominator, vilket รคr . I R kan vi lagra nรคmnaren i en variabel sรฅ hรคr:
nominator <- x-min(x)
Steg 2) Vi berรคknar nรคmnare: . 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 nรคmnare och nรคmnare.
normalize <- nominator/denominator
Steg 4) Fรถr att returnera vรคrde till anropande funktion mรฅste vi skicka normalize inuti return() fรถr att fรฅ utdata frรฅn funktionen.
return(normalize)
Steg 5) Vi รคr redo att anvรคnda funktionen genom att wrapaping allt innanfรถr fรคstet.
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)
}
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 repetitiv 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 hรคrleda kraften i en formel. Ovanstรฅende kod รคr lรคttare att lรคsa och undvik speciellt misstag nรคr du klistrar in koder.
Fungerar med skick
Ibland mรฅste vi inkludera villkor i en funktion fรถr att koden ska kunna returnera olika utdata.
I maskininlรคrningsuppgifter mรฅste vi dela upp datasetet mellan en tรฅguppsรคttning och en testuppsรคttning. Tรฅguppsรคttningen lรฅter algoritmen lรคra sig av data. Fรถr att testa vรฅr modells prestanda kan vi anvรคnda testsetet 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(). Tanken bakom รคr enkel, vi multiplicerar lรคngden pรฅ datasetet (dvs antalet observationer) med 0.8. Till exempel, om vi vill dela datamรคngden 80/20, och vรฅr datauppsรคttning innehรฅller 100 rader, kommer vรฅr funktion att multiplicera 0.8*100 = 80. 80 rader kommer att vรคljas ut fรถr att bli vรฅr trรคningsdata.
Vi kommer att anvรคnda luftkvalitetsdataset fรถr att testa vรฅr anvรคndardefinierade funktion. Luftkvalitetsdataset har 153 rader. Vi kan se det med koden nedan:
nrow(airquality)
Produktion:
## [1] 153
Vi kommer att gรฅ tillvรคga 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. Argumenttรฅget รคr en boolesk parameter. Om den รคr satt till TRUE skapar vรฅr funktion tรฅgdatasetet, annars skapar den testdatasetet.
Vi kan fortsรคtta som vi gjorde med normalise()-funktionen. Vi skriver koden som om det bara vore engรฅngskod och lindar sedan in allt med villkoret i kroppen fรถr att skapa funktionen.
Steg 1:
Vi mรฅste berรคkna lรคngden pรฅ datasetet. Detta gรถrs med funktionen nrow(). Nrow returnerar det totala antalet rader i datamรคngden. Vi kallar den variabla lรคngden.
length<- nrow(airquality) length
Produktion:
## [1] 153
Steg 2:
Vi multiplicerar lรคngden med 0.8. Det kommer att returnera antalet rader att vรคlja. Det ska vara 153*0.8 = 122.4
total_row <- length*0.8 total_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 kallas split
split <- 1:total_row split[1:5]
Produktion:
## [1] 1 2 3 4 5
split vรคljer de fรถrsta 122 raderna frรฅn datamรคngden. Till exempel kan vi se att vรฅr variabeldelning samlar vรคrdena 1, 2, 3, 4, 5 och sรฅ vidare. Dessa vรคrden kommer att vara indexet 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 den delade variabeln. 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 testdatauppsรคttningen 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 villkoret inuti kroppen av funktionen. Kom ihรฅg att vi har ett argumenttรฅg som รคr ett booleskt satt till TRUE som standard fรถr att returnera tรฅguppsรคttningen. Fรถr att skapa villkoret anvรคnder vi if-syntaxen:
if (train ==TRUE){
train_df <- airquality[split, ]
return(train)
} else {
test_df <- airquality[-split, ]
return(test)
}
Detta รคr det, vi kan skriva funktionen. Vi behรถver bara รคndra luftkvaliteten till df eftersom vi vill prova vรฅr funktion till ev dataram, inte bara luftkvalitet:
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)
}
}
Lรฅt oss prova vรฅr funktion pรฅ datauppsรคttningen fรถr luftkvalitet. vi borde ha ett tรฅgset med 122 rader och ett testset 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






