Funksjoner i R-programmering med eksempel
Hva er en funksjon i R?
A funksjon, i et programmeringsmiljø, er et sett med instruksjoner. En programmerer bygger en funksjon for å unngå gjenta samme oppgave, eller redusere kompleksitet.
En funksjon skal være
- skrevet for å utføre bestemte oppgaver
- kan eller kan ikke inkludere argumenter
- inneholde en kropp
- kan returnere én eller flere verdier.
En generell tilnærming til en funksjon er å bruke argumentdelen som innganger, mate kroppen del og til slutt returnere en produksjon. Syntaksen til en funksjon er følgende:
function (arglist) { #Function body }
R viktige innebygde funksjoner
Det er mange innebygde funksjoner i R. R matcher inndataparameterne dine med funksjonsargumentene, enten etter verdi eller etter posisjon, og utfører deretter funksjonskroppen. Funksjonsargumenter kan ha standardverdier: hvis du ikke spesifiserer disse argumentene, vil R ta standardverdien.
Merknader:
Det er mulig å se kildekoden til en funksjon ved å kjøre navnet på selve funksjonen i konsollen.
Vi vil se tre funksjonsgrupper i aksjon
- Generell funksjon
- Matematikkfunksjon
- Statistisk funksjon
Generelle funksjoner
Vi er allerede kjent med generelle funksjoner som cbind(), rbind(),range(),sort(),order()-funksjoner. Hver av disse funksjonene har en spesifikk oppgave, tar argumenter for å returnere en utgang. Følgende er viktige funksjoner man må kjenne til-
diff() funksjon
Hvis du jobber med tidsserier, må du stille serien ved å ta deres lagverdier. A stasjonær prosess tillater konstant gjennomsnitt, varians og autokorrelasjon over tid. Dette forbedrer hovedsakelig prediksjonen av en tidsserie. Det kan enkelt gjøres med funksjonen diff(). Vi kan bygge tilfeldige tidsseriedata med en trend og deretter bruke funksjonen diff() for å stille serien. Funksjonen diff() aksepterer ett argument, en vektor, og returnerer passende lagged og iterert forskjell.
Merknader: Vi trenger ofte å lage tilfeldige data, men for læring og sammenligning ønsker vi at tallene skal være identiske på tvers av maskiner. For å sikre at vi alle genererer de samme dataene, bruker vi set.seed()-funksjonen med vilkårlige verdier på 123. Set.seed()-funksjonen genereres gjennom prosessen med pseudotilfeldig tallgenerator som får alle moderne datamaskiner til å ha samme sekvens av tall. Hvis vi ikke bruker funksjonen set.seed(), vil vi alle ha forskjellig rekkefølge av tall.
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() funksjon
I mange tilfeller ønsker vi å vite lengde av en vektor for beregning eller som skal brukes i en for-løkke. Lengde()-funksjonen teller antall rader i vektor x. Følgende koder importerer bilens datasett og returnerer antall rader.
Merknader: length() returnerer antall elementer i en vektor. Hvis funksjonen sendes inn i en matrise eller en dataramme, returneres antall kolonner.
dt <- cars ## number columns length(dt)
Utgang:
## [1] 1
## number rows length(dt[,1])
Utgang:
## [1] 50
Matematiske funksjoner
R har en rekke matematiske funksjoner.
Operator | Tekniske beskrivelser |
---|---|
abs (x) | Tar den absolutte verdien av x |
log(x,base=y) | Tar logaritmen til x med grunntallet y; hvis base ikke er spesifisert, returnerer den naturlige logaritmen |
exp (x) | Returnerer eksponentialen til x |
sqrt (x) | Returnerer kvadratroten av x |
faktoriell (x) | Returnerer faktoren til 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)
Utgang:
## [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)
Utgang:
## [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)
Utgang:
## [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
Statistiske funksjoner
R standard installasjon inneholder et bredt spekter av statistiske funksjoner. I denne opplæringen skal vi kort se på den viktigste funksjonen..
Grunnleggende statistikkfunksjoner
Operator | Tekniske beskrivelser |
---|---|
gjennomsnitt (x) | Gjennomsnitt av x |
median(x) | Median av x |
var(x) | Varians av x |
sd(x) | Standardavvik på x |
skala (x) | Standard poengsum (z-poeng) av x |
kvantil (x) | Kvartilene til x |
sammendrag (x) | Sammendrag av x: gjennomsnitt, min, maks osv.. |
speed <- dt$speed speed # Mean speed of cars dataset mean(speed)
Utgang:
## [1] 15.4
# Median speed of cars dataset median(speed)
Utgang:
## [1] 15
# Variance speed of cars dataset var(speed)
Utgang:
## [1] 27.95918
# Standard deviation speed of cars dataset sd(speed)
Utgang:
## [1] 5.287644
# Standardize vector speed of cars dataset head(scale(speed), 5)
Utgang:
## [,1] ## [1,] -2.155969 ## [2,] -2.155969 ## [3,] -1.588609 ## [4,] -1.588609 ## [5,] -1.399489
# Quantile speed of cars dataset quantile(speed)
Utgang:
## 0% 25% 50% 75% 100% ## 4 12 15 19 25
# Summary speed of cars dataset summary(speed)
Utgang:
## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 4.0 12.0 15.0 15.4 19.0 25.0
Frem til dette punktet har vi lært mange R innebygde funksjoner.
Merknader: Vær forsiktig med klassen til argumentet, dvs. numerisk, boolsk eller streng. For eksempel, hvis vi trenger å sende en strengverdi, må vi omslutte strengen i anførselstegn: "ABC" .
Skrivefunksjon i R
I noen tilfeller må vi skrive vår egen funksjon fordi vi må utføre en bestemt oppgave og ingen ferdige funksjoner eksisterer. En brukerdefinert funksjon innebærer en navn, argumenter og en kroppen.
function.name <- function(arguments) { computations on the arguments some other code }
Merknader: En god praksis er å navngi en brukerdefinert funksjon som er forskjellig fra en innebygd funksjon. Det unngår forvirring.
En argumentfunksjon
I neste utdrag definerer vi en enkel kvadratisk funksjon. Funksjonen aksepterer en verdi og returnerer kvadratet av verdien.
square_function<- function(n) { # compute the square of integer `n` n^2 } # calling the function and passing value 4 square_function(4)
Kode Forklaring
- Funksjonen heter square_function; det kan kalles hva vi vil.
- Den mottar et argument "n". Vi spesifiserte ikke typen variabel slik at brukeren kan sende et heltall, en vektor eller en matrise
- Funksjonen tar input "n" og returnerer kvadratet av input. Når du er ferdig med å bruke funksjonen, kan vi fjerne den med rm()-funksjonen.
# etter at du har opprettet funksjonen
rm(square_function) square_function
På konsollen kan vi se en feilmelding: Feil: objektet 'square_function' ble ikke funnet som forteller at funksjonen ikke eksisterer.
Miljøavgrensning
I R, den miljø er en samling av objekter som funksjoner, variabler, dataramme, etc.
R åpner et miljø hver gang Rstudio blir spurt.
Det tilgjengelige miljøet på øverste nivå er globalt miljø, kalt R_GlobalEnv. Og vi har lokalmiljø.
Vi kan liste opp innholdet i det nåværende miljøet.
ls(environment())
Produksjon
## [1] "diff_ts" "dt" "speed" "square_function" ## [5] "ts" "x" "x_vector"
Du kan se alle variablene og funksjonene som er opprettet i R_GlobalEnv.
Listen ovenfor vil variere for deg basert på den historiske koden du kjører i R Studio.
Legg merke til at n, argumentet til square_function-funksjonen er ikke i dette globale miljøet.
A nytt miljøet er opprettet for hver funksjon. I eksemplet ovenfor skaper funksjonen square_function() et nytt miljø inne i det globale miljøet.
For å tydeliggjøre forskjellen mellom global og lokalmiljø, la oss studere følgende eksempel
Disse funksjonene tar en verdi x som et argument og legger den til y definere utenfor og inne i funksjonen
Funksjonen f returnerer utdata 15. Dette er fordi y er definert i det globale miljøet. Enhver variabel definert i det globale miljøet kan brukes lokalt. Variabelen y har verdien 10 under alle funksjonsanrop og er tilgjengelig når som helst.
La oss se hva som skjer hvis variabelen y er definert inne i funksjonen.
Vi må slippe "y" før vi kjører denne koden med rm r
Utgangen er også 15 når vi kaller f(5), men returnerer en feil når vi prøver å skrive ut verdien y. Variabelen y er ikke i det globale miljøet.
Til slutt bruker R den nyeste variabeldefinisjonen for å passere inne i kroppen til en funksjon. La oss vurdere følgende eksempel:
R ignorerer y-verdiene definert utenfor funksjonen fordi vi eksplisitt opprettet en ay-variabel inne i funksjonens kropp.
Multi argument funksjon
Vi kan skrive en funksjon med mer enn ett argument. Tenk på funksjonen kalt "tider". Det er en enkel funksjon som multipliserer to variabler.
times <- function(x,y) { x*y } times(2,4)
Utgang:
## [1] 8
Når skal vi skrive funksjon?
Dataforsker må gjøre mange repeterende oppgaver. Mesteparten av tiden kopierer og limer vi inn biter av kode gjentatte ganger. Normalisering av en variabel er for eksempel sterkt anbefalt før vi kjører en maskinlæring algoritme. Formelen for å normalisere en variabel er:
Vi vet allerede hvordan vi bruker funksjonene min() og max() i R. Vi bruker tibble-biblioteket til å lage datarammen. Tibble er så langt den mest praktiske funksjonen for å lage et datasett fra bunnen av.
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 vil fortsette i to trinn for å beregne funksjonen beskrevet ovenfor. I det første trinnet vil vi lage en variabel kalt c1_norm som er reskalering av c1. I trinn to kopierer og limer vi bare inn koden til c1_norm og endrer med c2 og c3.
Detalj av funksjonen med kolonnen c1:
Nominator: : data_frame$c1 -min(data_frame$c1))
Nevner: max(data_frame$c1)-min(data_frame$c1))
Derfor kan vi dele dem for å få den normaliserte verdien av kolonne c1:
(data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
Vi kan lage c1_norm, c2_norm og 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)
Utgang:
## [1] 0.3400113 0.4198788 0.8524394 0.4925860 0.5067991
Det fungerer. Vi kan kopiere og lime inn
data_frame$c1_norm <- (data_frame$c1 -min(data_frame$c1))/(max(data_frame$c1)-min(data_frame$c1))
endre deretter c1_norm til c2_norm og c1 til c2. Vi gjør det samme for å lage 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 omskalerte variablene c1, c2 og c3 perfekt.
Imidlertid er denne metoden utsatt for feil. Vi kan kopiere og glemme å endre kolonnenavnet etter innliming. Derfor er en god praksis å skrive en funksjon hver gang du trenger å lime inn samme kode mer enn to ganger. Vi kan omorganisere koden til en formel og kalle den når det er nødvendig. For å skrive vår egen funksjon, må vi gi:
- Navn: normalisere.
- antall argumenter: Vi trenger bare ett argument, som er kolonnen vi bruker i vår beregning.
- Kroppen: dette er rett og slett formelen vi ønsker å returnere.
Vi vil fortsette trinn for trinn for å lage funksjonen normalisere.
Trinn 1) Vi skaper nominator, som er . I R kan vi lagre nominatoren i en variabel som dette:
nominator <- x-min(x)
Trinn 2) Vi beregner nevner: . Vi kan replikere ideen til trinn 1 og lagre beregningen i en variabel:
denominator <- max(x)-min(x)
Trinn 3) Vi utfører delingen mellom nevneren og nevneren.
normalize <- nominator/denominator
Trinn 4) For å returnere verdi til å kalle funksjonen må vi sende normalize inside return() for å få utdata fra funksjonen.
return(normalize)
Trinn 5) Vi er klare til å bruke funksjonen ved å pakke alt inn i braketten.
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) }
La oss teste funksjonen vår med variabelen c1:
normalize(data_frame$c1)
Det fungerer perfekt. Vi opprettet vår første funksjon.
Funksjoner er en mer omfattende måte å utføre en repeterende oppgave på. Vi kan bruke normaliseringsformelen over forskjellige kolonner, som nedenfor:
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)
Selv om eksemplet er enkelt, kan vi utlede kraften til en formel. Koden ovenfor er lettere å lese og unngår spesielt feil når du limer inn koder.
Fungerer med tilstand
Noen ganger må vi inkludere betingelser i en funksjon for å la koden returnere forskjellige utdata.
I maskinlæringsoppgaver må vi dele datasettet mellom et togsett og et testsett. Togsettet lar algoritmen lære av dataene. For å teste ytelsen til modellen vår, kan vi bruke testsettet til å returnere ytelsesmålet. R har ikke en funksjon for å lage to datasett. Vi kan skrive vår egen funksjon for å gjøre det. Vår funksjon tar to argumenter og kalles split_data(). Tanken bak er enkel, vi multipliserer lengden på datasettet (dvs. antall observasjoner) med 0.8. For eksempel, hvis vi ønsker å dele datasettet 80/20, og datasettet vårt inneholder 100 rader, vil funksjonen vår multiplisere 0.8*100 = 80. 80 rader vil bli valgt for å bli treningsdataene våre.
Vi vil bruke luftkvalitetsdatasettet til å teste vår brukerdefinerte funksjon. Luftkvalitetsdatasettet har 153 rader. Vi kan se det med koden nedenfor:
nrow(airquality)
Utgang:
## [1] 153
Vi vil gå frem som følger:
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 funksjon har to argumenter. Argumenttoget er en boolsk parameter. Hvis den er satt til TRUE, oppretter funksjonen vår togdatasettet, ellers oppretter den testdatasettet.
Vi kan fortsette som vi gjorde med normalise()-funksjonen. Vi skriver koden som om det bare var engangskode og pakker så alt med betingelsen inn i kroppen for å lage funksjonen.
Trinn 1:
Vi må beregne lengden på datasettet. Dette gjøres med funksjonen nrow(). Nrow returnerer det totale antallet rader i datasettet. Vi kaller den variable lengden.
length<- nrow(airquality) length
Utgang:
## [1] 153
Steg XNUMX:
Vi multipliserer lengden med 0.8. Det vil returnere antall rader å velge. Det skal være 153*0.8 = 122.4
total_row <- length*0.8 total_row
Utgang:
## [1] 122.4
Vi ønsker å velge 122 rader blant de 153 radene i luftkvalitetsdatasettet. Vi lager en liste som inneholder verdier fra 1 til total_row. Vi lagrer resultatet i variabelen kalt split
split <- 1:total_row split[1:5]
Utgang:
## [1] 1 2 3 4 5
split velger de første 122 radene fra datasettet. For eksempel kan vi se at vår variabeldeling samler verdiene 1, 2, 3, 4, 5 og så videre. Disse verdiene vil være indeksen når vi velger radene som skal returneres.
Steg XNUMX:
Vi må velge radene i luftkvalitetsdatasettet basert på verdiene som er lagret i den delte variabelen. Dette gjøres slik:
train_df <- airquality[split, ] head(train_df)
Utgang:
##[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
Trinn 4:
Vi kan lage testdatasettet ved å bruke de resterende radene, 123:153. Dette gjøres ved å bruke – foran split.
test_df <- airquality[-split, ] head(test_df)
Utgang:
##[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
Trinn 5:
Vi kan skape tilstanden inne i funksjonens kropp. Husk at vi har et argumenttog som er et boolsk satt til TRUE som standard for å returnere togsettet. For å lage betingelsen bruker vi if-syntaksen:
if (train ==TRUE){ train_df <- airquality[split, ] return(train) } else { test_df <- airquality[-split, ] return(test) }
Dette er det, vi kan skrive funksjonen. Vi trenger kun å endre luftkvalitet til df fordi vi ønsker å prøve vår funksjon til evt Dataramme, ikke bare 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) } }
La oss prøve funksjonen vår på luftkvalitetsdatasettet. vi bør ha ett togsett med 122 rader og et testsett med 31 rader.
train <- split_data(airquality, train = TRUE) dim(train)
Utgang:
## [1] 122 6
test <- split_data(airquality, train = FALSE) dim(test)
Utgang:
## [1] 31 6