R
.quit()
lub q()
.Enter
.2*pi;cos(1)
## [1] 6.283185
## [1] 0.5403023
=
, <-
, <<-
<-
ma najwyższy priorytet i jest standardowym operatorem przypisania w R<<-
może byc wykorzystany w ciele funkcji jeśli chcemy wewnatrz funkcji nadac wartość zmiennej globalnej=
służy do podawania parametrów funkcjia <- 5
2 -> b
a;b
## [1] 5
## [1] 2
b = a <- 10
a;b
## [1] 10
## [1] 10
inkrementuj <- function(x){
x <<- x+1
}
x <- 1
inkrementuj(x)
x
## [1] 2
rnorm(n=3,mean=2,sd=0.5)
## [1] 3.158013 2.044482 2.094134
source()
ze sciezką do skryptu.#
.Source
.Ctrl+Enter
lub przycisk Run
.print()
i cat()
służą do wypisywania wartości zmiennych na ekran.x <- 2
y <- x+1
z <- x^2
cat("y =",y,"\n")
## y = 3
print(z)
## [1] 4
numeric
a <- 10
a; typeof(a)
## [1] 10
## [1] "double"
L
.b <- 10L
typeof(b)
## [1] "integer"
typeof(b+1)
## [1] "double"
typeof(b+1L)
## [1] "integer"
a+bi
.d <- 2+3i
d; typeof(d)
## [1] 2+3i
## [1] "complex"
sqrt(-1)
## Warning in sqrt(-1): NaNs produced
## [1] NaN
sqrt(-1+0i)
## [1] 0+1i
a <- 2.3e3
a
## [1] 2300
NaN
("nie liczba") oraz nieskonczoności Inf
, -Inf
1/0; exp(-Inf); 0 * Inf
## [1] Inf
## [1] 0
## [1] NaN
character
napis <- "Ala ma kota"
napis
## [1] "Ala ma kota"
napis <- 'Pakiet R'
napis; typeof(napis)
## [1] "Pakiet R"
## [1] "character"
paste()
slowo1 <- "I"
slowo2 <- "like"
slowo3 <- "trains"
paste(slowo1,slowo2,slowo3,sep=" ")
## [1] "I like trains"
character
NIE jest wektorem znaków.NA
- brak wartości).c()
tworzy wektor z pojedynczych elementów tego samego typu.v <- c(-1,2,5)
v
## [1] -1 2 5
seq()
lub zwyczajnym dwukropkiem.u <- 1:10
u
## [1] 1 2 3 4 5 6 7 8 9 10
w <- seq(-10,10,2)
w
## [1] -10 -8 -6 -4 -2 0 2 4 6 8 10
rep()
służy do generowania wektorów z powtórzeniami.x <- rep(TRUE, 5)
x
## [1] TRUE TRUE TRUE TRUE TRUE
y <- rep(c(1,2,3),3)
y
## [1] 1 2 3 1 2 3 1 2 3
z <- rep(c(1,2,3), each=3)
z
## [1] 1 1 1 2 2 2 3 3 3
factor()
.levels()
wypisuje poziomywyksztalcenie <- factor(c("podstawowe", "wyzsże", "srednie", "srednie", "wyzsże"))
wyksztalcenie
## [1] podstawowe wyzsże srednie srednie wyzsże
## Levels: podstawowe srednie wyzsże
levels(wyksztalcenie)
## [1] "podstawowe" "srednie" "wyzsże"
typeof(wyksztalcenie)
## [1] "integer"
wyksztalcenie+1
## Warning in Ops.factor(wyksztalcenie, 1): '+' not meaningful for factors
## [1] NA NA NA NA NA
list()
.L <- list(inty = 1:10, x = 2.71, tekst = c("a", "b", "c"), log = rep(T, 5))
L
## $inty
## [1] 1 2 3 4 5 6 7 8 9 10
##
## $x
## [1] 2.71
##
## $tekst
## [1] "a" "b" "c"
##
## $log
## [1] TRUE TRUE TRUE TRUE TRUE
matrix()
.A <- matrix(0, 2, 3); A
## [,1] [,2] [,3]
## [1,] 0 0 0
## [2,] 0 0 0
A <- matrix(1:8, 4, 2); A
## [,1] [,2]
## [1,] 1 5
## [2,] 2 6
## [3,] 3 7
## [4,] 4 8
A <- matrix(c("a", "b", "c", "d"),2 , 2); A
## [,1] [,2]
## [1,] "a" "c"
## [2,] "b" "d"
byrow=TRUE
.A <- matrix(1:8, 4, 2, byrow = TRUE); A
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
## [3,] 5 6
## [4,] 7 8
array()
A <- array(1:27, dim = c(3,3,3)); A
## , , 1
##
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
##
## , , 2
##
## [,1] [,2] [,3]
## [1,] 10 13 16
## [2,] 11 14 17
## [3,] 12 15 18
##
## , , 3
##
## [,1] [,2] [,3]
## [1,] 19 22 25
## [2,] 20 23 26
## [3,] 21 24 27
data.frame()
ramka <- data.frame(liczby = 5:1, logiczne = T); ramka
## liczby logiczne
## 1 5 TRUE
## 2 4 TRUE
## 3 3 TRUE
## 4 2 TRUE
## 5 1 TRUE
c()
lub dwukropka.w <- 11:20
w[1:5]
## [1] 11 12 13 14 15
w[-1]
## [1] 12 13 14 15 16 17 18 19 20
w[c(1:4,8)]
## [1] 11 12 13 14 18
w[c(-2,-5)]
## [1] 11 13 14 16 17 18 19 20
M <- matrix(1:9, 3, 3)
M
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
# Pierwszy wiersz
M[1,]
## [1] 1 4 7
# Pierwsza kolumna
M[,1]
## [1] 1 2 3
# Dwa pierwsze wiersże
M[1:2,]
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
# Bez trzeciej kolumny
M[,-3]
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
# Bez drugiego wiersza i drugiej kolumny
M[-2,-2]
## [,1] [,2]
## [1,] 1 7
## [2,] 3 9
$
tzn. nazwa_listy$nazwa_zmiennej
. Warto pamiętać, że pojedynczy nawias kwadratowy daje jedynie przecięcie listy (tzn. wynik jest listą) i aby otrzymać ten sam wynik, co w przypadku operatora $
, należy użyć nawiasu podwójnego [[...]].L <- list(inty = 1:10, x = 2.71, tekst = c("a", "b", "c"), log = rep(T, 5))
L$inty
## [1] 1 2 3 4 5 6 7 8 9 10
L[1]
## $inty
## [1] 1 2 3 4 5 6 7 8 9 10
L[[1]]
## [1] 1 2 3 4 5 6 7 8 9 10
ramka <- data.frame(liczby = 5:1, logiczne = T)
ramka
## liczby logiczne
## 1 5 TRUE
## 2 4 TRUE
## 3 3 TRUE
## 4 2 TRUE
## 5 1 TRUE
# Pierwsże trzy wiersże
ramka[1:3,]
## liczby logiczne
## 1 5 TRUE
## 2 4 TRUE
## 3 3 TRUE
# Druga kolumna
ramka[,2]
## [1] TRUE TRUE TRUE TRUE TRUE
# Pierwsza kolumna
ramka$liczby
## [1] 5 4 3 2 1
w[6:10][1:2]
## [1] 16 17
L[[3]][2:3]
## [1] "b" "c"
ramka$liczby[1:3]
## [1] 5 4 3
Zdefiniujmy następujące wektory w
, u
i macierze A
, B
:
w <- c(1,2)
v <- c(3,4)
A <- matrix(1:4, 2, 2)
B <- matrix(4:1, 2, 2)
w; v; A; B
## [1] 1 2
## [1] 3 4
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
## [,1] [,2]
## [1,] 4 2
## [2,] 3 1
W pakiecie R, podobnie zresztą jak w innych językach skryptowych (np. Matlab), wiekszość funkcji jest przeciążona że wzgledu na operacje wykonywane na wektorach i macierzach. Innymi słowy, operacje takie są wykonywane po kolejnych elementach wektora (lub macierzy) i zwracane jako podobny obiekt.
Możemy wykonywać następujące operacje na wektorach
w + v
,w + 5
,2 * w
,exp(w)
,w %*% v
.w + v
## [1] 4 6
5 + w
## [1] 6 7
2 * w
## [1] 2 4
sin(w)
## [1] 0.8414710 0.9092974
w %*% v
## [,1]
## [1,] 11
Podobna sytuacja dotyczy macierzy. Dodatkowo mamy do dyspozycji inne, bardzo przydatne funkcje obsługi macierzy:
A + B
,1 + A
,2 * A
,t(A)
,det(A)
,A %*% B
,eigen(A)
.A + B
## [,1] [,2]
## [1,] 5 5
## [2,] 5 5
1 + A
## [,1] [,2]
## [1,] 2 4
## [2,] 3 5
2 * A
## [,1] [,2]
## [1,] 2 6
## [2,] 4 8
t(A)
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
det(A)
## [1] -2
A %*% B
## [,1] [,2]
## [1,] 13 5
## [2,] 20 8
eigen(A)
## eigen() decomposition
## $values
## [1] 5.3722813 -0.3722813
##
## $vectors
## [,1] [,2]
## [1,] -0.5657675 -0.9093767
## [2,] -0.8245648 0.4159736
Następujące funkcje są bardzo przydatne podczas przetwarzania danych w formacie wektorowym:
x <- c(2,-1,0,3,-5)
length(x)
## [1] 5
mean(x)
## [1] -0.2
sd(x)
## [1] 3.114482
rev(x)
## [1] -5 3 0 -1 2
sum(x)
## [1] -1
cumsum(x)
## [1] 2 1 1 4 -1
prod(x)
## [1] 0
cumprod(x)
## [1] 2 -2 0 0 0
min(x)
## [1] -5
which.min(x)
## [1] 5
max(x)
## [1] 3
which.max(x)
## [1] 4
decreasing=TRUE
) malejącosort(x)
## [1] -5 -1 0 2 3
sort(x, decreasing = TRUE)
## [1] 3 2 0 -1 -5
index=TRUE
powoduje stworzenie listy, której pierwszym elementem x
jest posortowany wektor, drugim zaś ix
indeksy oryginalnych danych w posortowanym wektorzesort(x, index=TRUE)
## $x
## [1] -5 -1 0 2 3
##
## $ix
## [1] 5 2 3 1 4
NA
(brak wartości) - wtedy funkcje nie zwrócą oczekiwanego wyniku, chyba że zostanie zastosowana opcja na.rm=TRUE
.y <- c(1, NA, 2, 5, 7)
sum(y)
## [1] NA
mean(y)
## [1] NA
sum(y, na.rm = TRUE)
## [1] 15
mean(y, na.rm = TRUE)
## [1] 3.75
which()
podaje indeksy elementów spełniających określony warunek.which(y > 2)
## [1] 4 5
which(y == 2)
## [1] 3
which(y == NA)
wyświetli komunikat błędu. Aby znaleźć indeksy elementów NA
lub NaN
i +/-Inf
należy skorzystac z funkcji is.na()
, is.nan()
, is.finite()
oraz is.infinite()
wewnątrz funkcji which()
.z <- c(0/0, NA, 1/0, -1/0, 10, 15); z
## [1] NaN NA Inf -Inf 10 15
is.na(z)
## [1] TRUE TRUE FALSE FALSE FALSE FALSE
is.nan(z)
## [1] TRUE FALSE FALSE FALSE FALSE FALSE
is.infinite(z)
## [1] FALSE FALSE TRUE TRUE FALSE FALSE
which(is.na(z))
## [1] 1 2
which(is.nan(z))
## [1] 1
which(is.infinite(z))
## [1] 3 4
x <- 1:10
for(i in x) print(i)
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
x <- 1
while(x < 5) {
print(x)
x <- x + 1
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
x <- 5
if(x < 5) print(x) else print(x ^ 2)
## [1] 25
Warunek musi mieć długość równą 1, inaczej instrukcja warunkowa zostanie wykonana tylko dla pierwszego elementu.
x <- 1:10
if(x %% 3) {
print("Nie dzieli się przez 3")
} else {
print("Dzieli się przez 3")
}
## Warning in if (x%%3) {: the condition has length > 1 and only the first
## element will be used
## [1] "Nie dzieli się przez 3"
W przypadku, gdy mamy możliwość pracy na wektorze wartości, wygodnie jest korzystać z funkcji ifelse(), która sprawdza warunek dla każdego elementu wektora i zwraca również wektor.
x <- 1:10
ifelse(x %% 3, "Nie dzieli się przez 3", "Dzieli się przez 3")
## [1] "Nie dzieli się przez 3" "Nie dzieli się przez 3"
## [3] "Dzieli się przez 3" "Nie dzieli się przez 3"
## [5] "Nie dzieli się przez 3" "Dzieli się przez 3"
## [7] "Nie dzieli się przez 3" "Nie dzieli się przez 3"
## [9] "Dzieli się przez 3" "Nie dzieli się przez 3"
ZADANIE: W jaki inny sposób, bez użycia instrukcji ifelse()
ani innych pętli, mając wyżej zdefiniowany wektor x
wypisać liczby podzielne przez 3?
Skrypty w języku R uruchamiane są komendą source("nazwa_pilku")
lub, jeśli jest to aktualnie otwarty program w oknie, kombinacją klawiszy Ctrl+Shift+S
. Oczywiście, w przypadku używania własnych funkcji, należy je zdefiniowac przed główną częscią skryptu, czyli po prostu na górze. W odróżnieniu od linii komend, wypisanie na ekran trzeba ubrać w odpowiednią funkcję print()
lub cat()
.
# PLIK test.R
# Funkcja
f <- function(x, y) {
x <- 2*x
y <<- 2*y
}
# Główna część skryptu
x <- 2
y <- 2
print(x)
print(y)
x
f(2,2)
cat("x =",x,"\n")
cat("y =",y,"\n")
# Wykonanie skryptu: source("test.R")
Schemat tworzenia funkcji jest następujący
nazwa_funkcji <- function(x, y, ...) {
...
...
return(wartość)
}
Warto zaznaczyć, że funkcja może przyjmowac oraz zwracać nie tylko skalary, ale również wektory. Przykładem może byc funkcja realizująca "tabliczkę mnożenia" dla dowolnych dwoch wektorów.
tabliczka_mnożenia <- function(zakres1, zakres2) {
return(zakres1 %o% zakres2)
}
tabliczka_mnożenia(1:10,1:10)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 1 2 3 4 5 6 7 8 9 10
## [2,] 2 4 6 8 10 12 14 16 18 20
## [3,] 3 6 9 12 15 18 21 24 27 30
## [4,] 4 8 12 16 20 24 28 32 36 40
## [5,] 5 10 15 20 25 30 35 40 45 50
## [6,] 6 12 18 24 30 36 42 48 54 60
## [7,] 7 14 21 28 35 42 49 56 63 70
## [8,] 8 16 24 32 40 48 56 64 72 80
## [9,] 9 18 27 36 45 54 63 72 81 90
## [10,] 10 20 30 40 50 60 70 80 90 100
Instrukcja return()
nie jest obligatoryjna - za wartość funkcji przyjmowana jest wartość wyznaczona w ostatniej jej linii.
dodaj <- function(x, y) {
x*y
cos(x)
x+y
}
dodaj(2,5)
## [1] 7
Wszystkie wartości przekazane do funkcji są widoczne i zmieniane lokalnie. W przypadku potrzeby zmiany wartości zmiennej tak, aby była widoczna globalnie należy użyć operatora przypisania <<-
f <- function(x, y) {
x <- x * 2
y <<- y * 2
}
x <- 2
y <- 2
f(2,2)
x; y
## [1] 2
## [1] 4
ZADANIE: Napisz funkcję cross.prod(x,y)
, która będzie wykonywała iloczyn wektorowy dwóch wektorów.