Wektory
Tworzenie wektorów
Wektory są to skończone ciągi elementów tego samego typu (liczbowe, tekstowe, logiczne lub bardziej złożonych typów, np. wektor wektorów). Wektor można utworzyć i zapamiętać pod dowolną nazwą poprzez zastosowanie składni:
nazwa.wektora=c(x1,x2,…)Tworzenie wektorów poprzez stosowanie funkcji c(), o dowolnej liczbie argumentów rozdzielonych przecinkami, stosowane było i jest w niektórych starych językach programowania. W języku S, a po nim R, po prostu zastosowano tę nazwę.
> # utworzenie wektora liczb i zapamiętanie go pod nazwą "nazwa" > nazwa=c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1, 11.11, + 12.12, 13.13, 14.14, 15.15) > # zobaczenie co kryje się pod wektorem "nazwa" > nazwa [1] 1.10 2.20 3.30 4.40 5.50 6.60 7.70 8.80 9.90 10.10 11.11 [12] 12.12 13.13 14.14 15.15 > nazwa=c("ab", "ac", "ad", "bb", "bc", "bd", "ca", "cb", "cd", "ce", + "db", "dc", "de", "ea", "ef") [1] "ab" "ac" "ad" "bb" "bc" "bd" "ca" "cb" "cd" "ce" "db" "dc" "de" [14] "ea" "ef" > nazwa=c("a",1) > nazwa [1] "a" "1" |
Zastosowanie w ciągu wyrazów wektora choć jednego elementu o typie tekstowym powoduje, że wszystkie elementy tego ciągu będą typu tekstowego.
Wektory to uporządkowane ciągi. Elementy wektora nazywane są wyrazami. Każdy wyraz ma swoją pozycję w ciągu zwaną indeksem będącym liczba naturalną. Pierwszy wyraz ma indeks 1. Nie istnieje wyraz zerowy w żadnym wektorze.
Automatyczne tworzenie standardowych wektorów umożliwiają następujące wyrażenia i funkcje.
- integer(n) ciąg złożony z n zer o typie integer,
- numeric(n) ciąg złożony z n zer o typie double,
- double(n) ciąg złożony z n zer o typie double,
- n1:n2 (gdzie n1 i n2 są liczbami całkowitymi). Gdy n1<n2 powstaje ciąg rosnący n1, n1+1, n1+2,…,n2, gdy n1>n2 powstaje ciąg malejący n1, n1-1,… ,n2,
- seq(a,b,by=r) ciąg arytmetyczny o pierwszym wyrazie a, różnicy ciągu równej r i ostatnim wyrazie będącym liczbą nie większą niż b,
- rep(n,m) ciąg złożony z m liczb n,
- rep(x, times=n) ciąg złożony z n ciągów x jeden za drugim,
- rep(x, each=n) ciąg złożony z n powtórzeń każdego wyrazu ciągu x po kolei.
> -3:10 [1] -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 > 8:-4 [1] 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 > seq(-5.4,3.2,by=0.5) [1] -5.4 -4.9 -4.4 -3.9 -3.4 -2.9 -2.4 -1.9 -1.4 -0.9 -0.4 0.1 0.6 [14] 1.1 1.6 2.1 2.6 3.1 > seq(-5.4,3.2,length=18) [1] -5.4000000 -4.8941176 -4.3882353 -3.8823529 -3.3764706 -2.8705882 [7] -2.3647059 -1.8588235 -1.3529412 -0.8470588 -0.3411765 0.1647059 [13] 0.6705882 1.1764706 1.6823529 2.1882353 2.6941176 3.2000000 > rep(1,30) [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 > c=c(1,3,2,0) > rep(c, times=5) [1] 1 3 2 0 1 3 2 0 1 3 2 0 1 3 2 0 1 3 2 0 > rep(c, each=5) [1] 1 1 1 1 1 3 3 3 3 3 2 2 2 2 2 0 0 0 0 0 |
Funkcja seq() pozwala także na automatyczne tworzenie wektorów zawierających daty i czas. Jest to przydatne zwłaszcza przy tworzeniu kalendarza dla zbieranych danych, gdyż liczba dni w poszczególnych miesiącach i latach nie jest taka sama.
> seq(as.Date("2020-01-01"), as.Date("2020-03-01"), by="days") [1] "2020-01-01" "2020-01-02" "2020-01-03" "2020-01-04" "2020-01-05" "2020-01-06" [7] "2020-01-07" "2020-01-08" "2020-01-09" "2020-01-10" "2020-01-11" "2020-01-12" [13] "2020-01-13" "2020-01-14" "2020-01-15" "2020-01-16" "2020-01-17" "2020-01-18" [19] "2020-01-19" "2020-01-20" "2020-01-21" "2020-01-22" "2020-01-23" "2020-01-24" [25] "2020-01-25" "2020-01-26" "2020-01-27" "2020-01-28" "2020-01-29" "2020-01-30" [31] "2020-01-31" "2020-02-01" "2020-02-02" "2020-02-03" "2020-02-04" "2020-02-05" [37] "2020-02-06" "2020-02-07" "2020-02-08" "2020-02-09" "2020-02-10" "2020-02-11" [43] "2020-02-12" "2020-02-13" "2020-02-14" "2020-02-15" "2020-02-16" "2020-02-17" [49] "2020-02-18" "2020-02-19" "2020-02-20" "2020-02-21" "2020-02-22" "2020-02-23" [55] "2020-02-24" "2020-02-25" "2020-02-26" "2020-02-27" "2020-02-28" "2020-02-29" [61] "2020-03-01" > seq(as.Date("2021-01-01"), as.Date("2021-03-01"), by="days") [1] "2021-01-01" "2021-01-02" "2021-01-03" "2021-01-04" "2021-01-05" "2021-01-06" [7] "2021-01-07" "2021-01-08" "2021-01-09" "2021-01-10" "2021-01-11" "2021-01-12" [13] "2021-01-13" "2021-01-14" "2021-01-15" "2021-01-16" "2021-01-17" "2021-01-18" [19] "2021-01-19" "2021-01-20" "2021-01-21" "2021-01-22" "2021-01-23" "2021-01-24" [25] "2021-01-25" "2021-01-26" "2021-01-27" "2021-01-28" "2021-01-29" "2021-01-30" [31] "2021-01-31" "2021-02-01" "2021-02-02" "2021-02-03" "2021-02-04" "2021-02-05" [37] "2021-02-06" "2021-02-07" "2021-02-08" "2021-02-09" "2021-02-10" "2021-02-11" [43] "2021-02-12" "2021-02-13" "2021-02-14" "2021-02-15" "2021-02-16" "2021-02-17" [49] "2021-02-18" "2021-02-19" "2021-02-20" "2021-02-21" "2021-02-22" "2021-02-23" [55] "2021-02-24" "2021-02-25" "2021-02-26" "2021-02-27" "2021-02-28" "2021-03-01" |
Inne opcje, jakie wtedy można dodać do funkcji seq(), to length.out=n – liczba dat lub okresów czasowych jaka ma być w wektorze i along.with=x, gdzie x jest jakimś wektorem do którego dopasowujemy kolejne daty.
Każda wielkość liczbowa, znakowa, tekstowa i logiczna traktowana jest jako wektor jednoelementowy. Wektor może być dowolnej długości ograniczony tylko rozmiarami pamięci operacyjnej. Ponadto można zdefiniować wektor pusty (0 elementowy) instrukcją przypisania:
x=NULLx=numeric(0), gdy wiemy, że x to wektor liczbowyx=character(0), gdy wiemy, że x to wektor tekstowyx=logical(0), gdy wiemy, że x to wektor logicznyJest to bardzo przydatne, gdy opracowanie danych wiąże się z sekwencyjnym uzyskiwaniem wyników, które dopisujemy do wektora “wynik”. Wtedy na początku przypisujemy mu wartość wynik=NULL, a potem stosujemy instrukcję wynik=c(wynik, kolejna_wartość).
Nazywanie elementów wektora
Niekiedy poszczególne elementy wektora mają swoje nazwy. Takie wektory tworzy się przypisując nazwom elementy wektora. Wygląda to następująco:
> wek=c(Ala=1.1, Ola=2.2, Ela=3.3, Ula=4.4, Iga=5.5) > wek Ala Ola Ela Ula Iga 1.1 2.2 3.3 4.4 5.5 > wek=c("Ala"=1.1, "Ola"=2.2, "Ela"=3.3, "Ula"=4.4, "Iga"=5.5) > wek Ala Ola Ela Ula Iga 1.1 2.2 3.3 4.4 5.5 |
Nazwy można wpisać w cudzysłowie lub bez. R potraktuje je jako teksty.
Nazywanie elementów ciągu może być zautomatyzowane. Nazwy mogą się powtarzać lub być puste.
> nazwa=c(liczba=c(3.1, 2.2, 1.3, 7.4, 6.5, 5.6, 4.7)) > nazwa liczba1 liczba2 liczba3 liczba4 liczba5 liczba6 liczba7 3.1 2.2 1.3 7.4 6.5 5.6 4.7 > a=c(L=c(1, 3, 2.2, 5)) > b=c(2, 4, 5.4, 6) > c(a,b) L1 L2 L3 L4 1.0 3.0 2.2 5.0 2.0 4.0 5.4 6.0 > b=c(L=c(2, 4, 5.4, 6)) > c(a,b) L1 L2 L3 L4 L1 L2 L3 L4 1.0 3.0 2.2 5.0 2.0 4.0 5.4 6.0 |
Innym sposobem nazywania elementów wektora utworzonego wcześniej jest użycie funkcji names().
> populacja=c(1732707, 707504, 760701, 633802, 546503) > names(populacja)=c("Warszawa", "Łódź", "Kraków", "Wrocław", "Poznań") > populacja Warszawa Łódź Kraków Wrocław Poznań 1732707 707504 760701 633802 546503 |
Funkcja names() pozwala nie tylko nazywać wyrazy ciągu, ale także umożliwia wyświetlanie nazw elementów wektora, o ile istnieją.
> a=c(L=c(1, 3, 2.2, 5)) > b=c(2, 4, 5.4, 6) > c(a,b) L1 L2 L3 L4 1.0 3.0 2.2 5.0 2.0 4.0 5.4 6.0 > names(a) [1] "L1" "L2" "L3" "L4" > names(b) NULL > names(c) [1] "L1" "L2" "L3" "L4" "" "" "" "" |
Zmianę nazw wektora w można uzyskać poprzez zwykła przypisanie nowych nazw wektorowi names(w). Ma to postać names(w)=ciąg_nowych_nazw.
Pozbycie się nazw elementów z jakiegoś ciągu można uzyskać stosując również funkcję names() w postaci names(ciag)=NULL.
> a=c(L=c(1, 3, 2.2, 5)) > a L1 L2 L3 L4 1.0 3.0 2.2 5.0 > names(a) = NULL > a [1] 1.0 3.0 2.2 5.0 |
Wektory zaimplementowane do R
Do R zaimplementowano kilka przydatnych stałych będących wektorami tekstowymi.
- LETTERS duże litery alfabetu łacińskiego w porządku alfabetycznym,
- letters małe litery alfabetu łacińskiego w porządku alfabetycznym,
- month.abb trzyliterowe skróty angielskich nazw miesięcy,
- month.name angielskie nazwy miesięcy.
> LETTERS [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" [18] "R" "S" "T" "U" "V" "W" "X" "Y" "Z" > letters [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" [18] "r" "s" "t" "u" "v" "w" "x" "y" "z" > month.abb [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" [12] "Dec" > month.name [1] "January" "February" "March" "April" "May" [6] "June" "July" "August" "September" "October" [11] "November" "December" |
Wektor islands jest z kolei wektorem liczbowym z nazwanymi wyrazami pokazującym powierzchnie największych obszarów lądowych kuli ziemskiej. Powierzchnie te wyrażone są w tysiącach mil kwadratowych (1 mi2= 2,59 km2).
> islands Africa Antarctica Asia Australia Axel Heiberg 11506 5500 1 6988 2968 16 Baffin Banks Borneo Britain Celebes 184 23 280 84 73 Celon Cuba Devon Ellesmere Europe 25 43 21 82 3745 Greenland Hainan Hispaniola Hokkaido Honshu 840 13 30 30 89 Iceland Ireland Java Kyushu Luzon 40 33 49 14 42 Madagascar Melville Mindanao Moluccas New Britain 227 16 36 29 15 New Guinea New Zealand (N) New Zealand (S) Newfoundland North America 306 44 58 43 9390 Novaya Zemlya Prince of Wales Sakhalin South America Southampton 32 13 29 6795 16 Spitsbergen Sumatra Taiwan Tasmania Tierra del Fuego 15 183 14 26 19 Timor Vancouver Victoria 13 12 82 |
Nie-amerykanom czasem mogą się przydać zaimplementowane do R trzy wektory charakteryzujące 50 stanów USA:
- state.abb – dwuliterowe skróty nazw poszczególnych stanów,
- state.area – powierzchnie poszczególnych stanów w milach kwadratowych,
- state.name – pełne nazwy poszczególnych stanów.
> state.name [1] “Alabama” “Alaska” “Arizona” “Arkansas” “California” [6] “Colorado” “Connecticut” “Delaware” “Florida” “Georgia” [11] “Hawaii” “Idaho” “Illinois” “Indiana” “Iowa” [16] “Kansas” “Kentucky” “Louisiana” “Maine” “Maryland” [21] “Massachusetts” “Michigan” “Minnesota” “Mississippi” “Missouri” [26] “Montana” “Nebraska” “Nevada” “New Hampshire” “New Jersey” [31] “New Mexico” “New York” “North Carolina” “North Dakota” “Ohio” [36] “Oklahoma” “Oregon” “Pennsylvania” “Rhode Island” “South Carolina” [41] “South Dakota” “Tennessee” “Texas” “Utah” “Vermont” [46] “Virginia” “Washington” “West Virginia” “Wisconsin” “Wyoming” > state.abb [1] “AL” “AK” “AZ” “AR” “CA” “CO” “CT” “DE” “FL” “GA” “HI” “ID” “IL” “IN” “IA” “KS” “KY” [28] “LA” “ME” “MD” “MA” “MI” “MN” “MS” “MO” “MT” “NE” “NV” “NH” “NJ” “NM” “NY” “NC” “ND” [35] “OH” “OK” “OR” “PA” “RI” “SC” “SD” “TN” “TX” “UT” “VT” “VA” “WA” “WV” “WI” “WY” > state.area [1] 51609 589757 113909 53104 158693 104247 5009 2057 58560 58876 6450 83557 [13] 56400 36291 56290 82264 40395 48523 33215 10577 8257 58216 84068 47716 [25] 69686 147138 77227 110540 9304 7836 121666 49576 52586 70665 41222 69919 [37] 96981 45333 1214 31055 77047 42244 267339 84916 9609 40815 68192 24181 [49] 56154 97914 |
Takich wektorów zaimplementowanych do R jest wiele. Wykaz wszystkich obiektów z danymi wprowadzonych do R, których oglądanie i używanie nie wymaga instalowania nowych bibliotek, można zobaczyć na stronie “http://127.0.0.1:28315/library/datasets/html/00Index.html#M”, na którą można przejść z R wpisując w konsoli ?datasets, a na wyświetlonej stronie klikając na index. W większości są to jednak bardziej złożone obiekty niż wektor (najczęściej bazy danych), o których będzie mowa w dalszych rozdziałach.
Odwołanie się do wybranych wyrazów wektora
Odwołanie się do i-tego wyrazu wektora zapamiętanego pod nazwą v polega na napisaniu v[i]. Indeksy są liczbami naturalnymi od 1 do d gdzie d jest długością wektora, ale R dopuszcza wpisanie za indeks liczby rzeczywistej, którą zamienia sam na liczbę całkowitą odcinając jej część ułamkową. Można odwołać się do kilku na raz wyrazów danego wektora, pod warunkiem, że odpowiednia lista indeksów jest ciągiem. Wynikiem takiego odwołania jest wektor złożony z jednego lub kilku wyrazów wektora wyjściowego bądź też wartości pomijalnej NA, gdy dla danego indeksu ciąg nie ma określonego wyrazu.
> v=0:10 > v[1] [1] 0 > v[0] integer(0) > v[5.5] [1] 4 > v[7:10] [1] 6 7 8 9 > v[12] [1] NA > v[7:12] [1] 6 7 8 9 10 NA > v[c(1,4,7)] [1] 0 3 6 |
Odwołać się można do wybranych elementów wektora poprzez eliminację wyrazów na wybranych miejscach. Ciąg eliminowanych wyrazów należy poprzedzić znakiem -.
> v=0:10 > v[-1] [1] 1 2 3 4 5 6 7 8 9 10 > v[-7:10] [1] 0 1 2 3 4 5 > v[-12] [1] NA > v[-c(1,4,7)] [1] 1 2 4 5 7 8 9 10 |
Gdy wektor ma nazwane elementy można do nich odwołać się poprzez nazwę.
> x=c(Ala=1, Ola=3, Ela=7, Ula=11) > x Ala Ola Ela Ula 1 3 7 11 > x["Ula"] Ula 11 |
Odwołanie się do szczególnych wyrazów wektora może zachodzić także poprzez warunek logiczny. Wynikiem jest wektor złożony z wyrazów ciągu wyjściowego spełniających ten warunek.
> v=0:10 > v[c(TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,FALSE,FALSE,TRUE,TRUE,FALSE)] [1] 0 1 4 5 8 9 > v[v>5] [1] 6 7 8 9 10 > v[v%%2==0] [1] 0 2 4 6 8 10 |
Edycja wektorów
Zamianę i-tej wartości wektora na inną wykonuje się poprzez odwołanie się do i-tej wartości i zastosowanie instrukcji przypisania. Można w ten sposób zmienić wartości całych grup wyrazów, a stosując warunki logiczne można wyliczyć np. wartości bezwzględne (moduły) kolejnych wyrazów ciągu.
> v=c(1.10, -2.20, 13.30, -4.40, 5.50, -6.60, 7.70, -8.80, 9.90, -10.10) > v[5]=-7 > v [1] 1.1 -2.2 13.3 -4.4 -7.0 -6.6 7.7 -8.8 9.9 -10.1 > v[v<0]=-v[v<0] > v [1] 1.1 2.2 13.3 4.4 7.0 6.6 7.7 8.8 9.9 10.1 > v[c(1,3,5,7,9)]=c(-1,-2,-3,-4,-5) > v [1] -1.0 2.2 -2.0 4.4 -3.0 6.6 -4.0 8.8 -5.0 10.1 |
Utworzony wektor czasem trzeba poprawić skreślając w nim pewne elementy. Skreślanie elementów polega na napisaniu indeksów elementów, które chcemy wyrzucić ze znakiem -.
> v=c(1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9) > v[-1] [1] 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 > v=v[-1:3] Błąd w poleceniu 'v[-1:3]':tylko zera mogą być mieszane z ujemnymi indeksami > v=v[-(1:3)] > v [1] 4.4 5.5 6.6 7.7 8.8 9.9 > v=v[-3:-20] > v [1] 1.1 2.2 |
Dodawanie nowych elementów do wektora na jego końcu i automatycznie wydłużenie go, łączenie dwóch wektorów, realizowane jest poprzez zastosowanie funkcji c(). Dodanie elementu x do wektora ma postać: c(wektor,x) a łączenie dwóch wektorów wygląda następująco c(wektor1,wektor2).
> v=c("a1", "b2", "c3", "d4", "e5", "f6", "g7") > w=c(v,"h8") > w [1] "a1" "b2" "c3" "d4" "e5" "f6" "g7" "h8" > c(w,c("k11","l12")) [1] "a1" "b2" "c3" "d4" "e5" "f6" "g7" "h8" "k11" "l12" > c(v[1:5],w[6:8]) [1] "a1" "b2" "c3" "d4" "e5" "f6" "g7" "h8" |
To samo można uzyskać za pomocą funkcji append(). Funkcja ta ma opcje pozwalające na wpisanie wektora wymienionego z prawej wewnątrz wektora wymienionego z lewej za pomocą opcji after=n, gdzie n jest liczbą naturalną pokazującą po ilu wyrazach wektora z lewej ma być dołączony wektor z prawej. Spełnia zatem taką rolę jak funkcje wstaw (insert) w innych językach programowania.
> v=c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1) > v [1] 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.1 > append(v, 0:5, after=3) [1] 1.1 2.2 3.3 0.0 1.0 2.0 3.0 4.0 5.0 4.4 5.5 6.6 7.7 8.8 9.9 10.1 |
Możliwe jest także ręczne poprawianie utworzonego wcześniej wektora przez jego wyświetlenie go za pomocą funkcji fix(), zmianę, wstawienie lub usunięcie wybranego wyrazu i zapamiętanie zmian. Funkcja fix() zastosowana na wektorze tworzy okienko podobne do skryptu, gdzie działa mysz i edycja jest prosta.
Zmiany należy później zapamiętać. Po zapamiętaniu możemy wrócić do konsoli i operować zmienionym wektorem do końca sesji. Jeżeli chcemy by obiekt w postaci tego wektora istniał i był na stale zmieniony należy przy wychodzeniu z R zapamiętać obszar roboczy.
Działania na wektorach liczbowych
W matematyce działania +, -, *, /, ^ wstawiane są między dwie liczby. Tak samo dzieje się w R, co pokazano w rozdziale 1. Jednak w R działania te zostały uogólnione na dowolne wektory i należy zobaczyć jak to działa.
Dodawanie i odejmowanie wektorów jest takie same jak w matematyce, gdy wektory są tej samej długości. Jest definiowane następująco:
(a1, a2, …,an) + (b1, b2, …, bn) = (a1 + b1, a2 + b2, …, an + bn)(a1, a2, …,an) – (b1, b2, …, bn) = (a1 – b1, a2 – b2, …, an – bn)W R uogólniono tę definicje na sumę wektorów o różnej długości. Przyjęto zasadę, że wektor krótszy jest wydłużany do długości wektora dłuższego w taki sposób, że dopisywane są do jego końca kolejne jego wyrazy od początku począwszy. Wygląda to następująco:
> c(1,2,3) + 4 [1] 5 6 7 > c(1, 2, 3)+c(4,5) [1] 5 7 7 Komunikat ostrzegawczy: W poleceniu 'c(1, 2, 3) + c(4, 5)': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu > c(1,2,3)+c(4,5,6) [1] 5 7 9 > c(1,2,3)+c(4,5,6,7) [1] 5 7 9 8 Komunikat ostrzegawczy: W poleceniu 'c(1, 2, 3) + c(4, 5, 6, 7)': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu |
W przypadku gdy różnice długości wektorów są takie, że nie można wektora dłuższego wyrazić jako wielokrotności wektora krótszego – pojawia się komunikat ostrzegawczy, choć działanie zostaje wykonane.
Zupełnie tak samo zdefiniowano mnożenie, dzielenie i potęgowanie wektorów. Nie są to działania stosowane w matematyce w rachunku wektorowym i nie powinny być mylone z różnymi odmianami mnożenia wektorów, np. z iloczynem tensorowym.
> c(1,2,3)*4 [1] 4 8 12 > c(1, 2, 3)*c(4,5) [1] 4 10 12 Komunikat ostrzegawczy: W poleceniu 'c(1, 2, 3) * c(4, 5)': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu > c(1,2,3)*c(4,5,6) [1] 4 10 18 > c(1,2,3)*c(4,5,6,7) [1] 4 10 18 8 Komunikat ostrzegawczy: W poleceniu 'c(1, 2, 3) * c(4, 5, 6, 7)': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu |
Jest możliwe także podniesienie do potęgi wyrażającej sie wektorem dowolnego wektora liczbowego.
> c(1,2,3)^4 [1] 1 16 81 > c(1, 2, 3)^c(4,5) [1] 1 32 81 Komunikat ostrzegawczy: W poleceniu 'c(1, 2, 3)^c(4, 5)': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu > c(1,2,3)^c(4,5,6) [1] 1 32 729 > c(1,2,3)^c(4,5,6,7) [1] 1 32 729 1 Komunikat ostrzegawczy: W poleceniu 'c(1, 2, 3) ^ c(4, 5, 6, 7)': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu |
Analogiczne zasady dotyczą także działań na liczbach całkowitych: wyliczania reszty z dzielenia %% oraz wyliczania ile razy liczba z prawej mieści się w lewej %/%.
Relacje dla wektorów liczbowych.
Zasada wydłużania krótszego wektora do długości dłuższego, poprzez powtarzanie wyrazów i porównywania ze sobą liczb na tych samych pozycjach, obowiązuje także dla relacji. Wygląda to następująco:
> x=c(-1,1,-1,1,-1,1) > x [1] -1 1 -1 1 -1 1 > y=-1:1 > y [1] -1 0 1 > x == y [1] TRUE FALSE FALSE FALSE FALSE TRUE > x < y [1] FALSE FALSE TRUE FALSE TRUE FALSE > y>=x [1] TRUE FALSE TRUE FALSE TRUE TRUE |
Specyficzną relacją jest sprawdzanie czy jakiś element lub elementy wektora występują w jakimś innym wektorze. Służy do tego relacja %in%
> x=c(-1,1,-1,1,-1,1) > x [1] -1 1 -1 1 -1 1 > y=-1:1 > y [1] -1 0 1 > -1 %in% x [1] TRUE > 0 %in% x [1] FALSE > y %in% x [1] TRUE FALSE TRUE |
Wynikiem zastosowanie relacji %in%, jest wektor o długości takiej samej, jak wektor z lewej strony, o wartości logicznych pokazujących, czy odpowiedni wyraz pierwszego wektora znajduje się w obrębie drugiego wektora.
Funkcje matematyczne na wektorach liczbowych.
Znane z lekcji matematyki funkcje liczbowe zostały szczegółowo opisane w rozdziale “Operacje na liczbach” i podrozdziale “Funkcje matematyczne”. Wszystkie je można zastosować na wektorach liczbowych zgodnie z zasadą:
Wyrazy wektora, które nie mieszczą się w dziedzinie funkcji f() zostają po przekształceniu zamienione na NaN.
> x=-3:3/2 > x [1] -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 > exp(x) [1] 0.2231302 0.3678794 0.6065307 1.0000000 1.6487213 2.7182818 4.4816891 > log(x,2) [1] NaN NaN NaN -Inf -1.0000000 0.0000000 0.5849625 Komunikat ostrzegawczy: wyprodukowano wartości NaN > gamma(x) [1] 2.3632718 NaN -3.5449077 NaN 1.7724539 1.0000000 0.8862269 Komunikat ostrzegawczy: W poleceniu 'gamma(x)': wyprodukowano wartości NaN |
Obok opisanego uogólnienia funkcji matematycznych, są w R funkcje przekształcające wektor na wektor. Dotyczy to sortowania, inwersji elementów ciągu i innych operacji. Najważniejsze z nich to:
- rev() ciąg zapisany w odwrotnej kolejności,
- sort() dane od najmniejszej do największej,
- order() pozycje elementów wektora począwszy od wartości najmniejszej do największej,
- rank() rangi kolejnych elementów wektora – numery elementów wektora, gdy posortuje się je w kolejności od najmniejszej do największej, przy czym elementom o tej samej wartości przypisuje się średnią arytmetyczną z odpowiadających im numerów,
- diff() różnice między kolejnymi wyrazami wektora,
- cumsum() ciąg sum wyrazów od pierwszego do i-tego.
- cumprod() ciąg iloczynów wyrazów od pierwszego do i-tego.
- cummin() ciąg najmniejszych wyrazów wektora od pierwszego do i-tego.
- cummax() ciąg największych wyrazów wektora od pierwszego do i-tego.
> wek=c(5.5, 2.2, 8.8, 4.4, 5.5, 8.8) > rev(wek) [1] 8.8 5.5 4.4 8.8 2.2 5.5 > sort(wek) [1] 2.2 4.4 5.5 5.5 8.8 8.8 > order(wek) [1] 2 4 1 5 3 6 > rank(wek) [1] 3.5 1.0 5.5 2.0 3.5 5.5 > diff(wek) [1] -3.3 6.6 -4.4 1.1 3.3 > cumsum(wek) [1] 5.5 7.7 16.5 20.9 26.4 35.2 > cumprod(wek) [1] 5.500 12.100 106.480 468.512 2576.816 22675.981 > cummin(wek) [1] 5.5 2.2 2.2 2.2 2.2 2.2 > cummax(wek) [1] 5.5 5.5 8.8 8.8 8.8 8.8 |
Szczególną rolę odgrywa funkcja which(). Jej argumentem musi być ciąg o wartościach logicznych skonstruowany zgodnie z zasadą: nazwa_wektora==inny_wektor, a wartościami są indeksy wyrazów wektora, dla których nazwa_wektora==inny_wektor ma wartość TRUE.
> ciag = c(10.1, 8.2, 3.3, 6.4, 5.5, 6.0, 3.7, 8.8, 9.9, 1.1, 2.0, 6.12, 5.1, 4.14, 3.0) > ciag==round(ciag,0) [1] [1] FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE FALSE [13] FALSE FALSE TRUE > which(ciag==round(ciag,0)) [1] 6 11 15 |
Zastosowana funkcja which() pokazała miejsca, gdzie w wektorze ciag znajdywały się liczby całkowite.
Funkcje statystyczne na wektorach liczbowych.
Funkcje statystyczne są funkcjami matematycznymi, ale dość specyficznymi. Działają bowiem na całych wektorach o dowolnej długości dając często w wyniku jedną liczbę. Pojawiły się w matematyce dopiero gdzieś w XXVII wieku i służyły powstałym wtedy urzędom państwowym do charakteryzowania populacji ludzkiej zamieszkującej dany kraj. Zaczęły odgrywać one dużą rolę w organizacji i funkcjonowaniu państwa. Opracowanie takich danych (w tym tworzenie i interpretacja sensownych funkcji przekształcających te dane) została nazwana statystyką (od łac. status = państwo). Dość szybko znalazły one zastosowanie w innych dziedzinach nauki, gdzie dokonuje się pomiarów obiektów w jakiś zbiorowościach i wykonuje szereg eksperymentów dających wyniki liczbowe.
Dziedziną funkcji matematycznych jest liczba, para liczb lub wektory o konkretnej długości. Zbór wszystkich wektorów o długości n oznaczyć można Rn, gdzie R jest zbiorem liczb rzeczywistych. Dziedziną funkcji statystycznych są wektory o dowolnej długości, czyli zbiór ∪nRn. Nie jest to jedyna różnica. Funkcje statystyczne mają bowiem to do siebie, że ich wynik charakteryzuje wektor w sensowny, interpretowalny sposób.
Podstawowe funkcje charakteryzujące wektor to:
- length() liczba elementów wektora,
- min() najmniejszy element wektora,
- max() największy element wektora,
- which.min() miejsce pierwszego najmniejszego elementu wektora,
- which.max() miejsce pierwszego największego elementu wektora,
- range(nazwa) wartość minimalna i maksymalna wektora.
> w = 0:10 > length(w) [1] 11 > min(w) [1] 0 > which.min(w) [1] 1 > range(w) [1] 0 10 |
Gdy opracowanie danych wymaga nie tylko wyliczenia np. wartości minimalnej wektora, ale policzenia ile wyrazów ma wartość minimalną i w których miejscach wektora się one znajdują, należy postępować w następujący sposób:
> w=c(7,3,8,3,9,3,11,3,11) > min(w) [1] 3 > w==min(w) [1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE > w[w==min(w)] [1] 3 3 3 3 > #liczba wartości minimalnych > length(w[w==min(w)]) [1] 4 > #miejsca wartości minimalnych > which(w==min(w)) [1] 2 4 6 8 |
Wektor wyników pomiarów osobników jakiejś badanej populacji, komórek jakiejś tkanki i innych obiektów biologicznych nazywany jest w biologii (i statystyce) próbą. Funkcje charakteryzujące taki wektor nazywane są charakterystykami z próby. Najważniejsze z tych funkcji to:
- sum() suma wszystkich elementów,
- prod() iloczyn wszystkich elementów,
- mean(nazwa) średnia arytmetyczna,
- mean(nazwa,trim=0.05) średnia arytmetyczna po odrzuceniu 5% skrajnych wyników,
- median(nazwa) mediana wektora,
- quantile(nazwa,p) kwantyl rzędu p,
- sd(nazwa)odchylenie standardowe z próby,
- var(nazwa) wariancja z próby.
> w = c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1, 11.11, 12.12, 13.13, 14.14, 15.15) > mean(w) [1] 8.35 > var(w) [1] 19.51486 > sd(w) [1] 4.417562 > min(w) [1] 1.1 > max(w) [1] 15.15 > median(w) [1] 8.8 |
Warto zaznaczyć, że wariancja, var(), wyliczana jest ze wzoru:
gdzie
Odchylenie standardowe wyliczne za pomocą funkcji sd() jest pierwiastkiem z tak wyliczanej wariancji.
Niektóre (stare) podręczniki do opracowania danych podają następujący wzór na wyliczenie wariancji:
Wzór ten nie obowiązuje dla wariancji liczonej obecnie według podanego pierwszego wzoru. Jest on prawdziwy dla wariancji wyliczanej jako suma kwadratów odchyleń danych od średniej podzielona przez n, nie n-1.
Jedną z najczęściej używanych funkcji statystycznych wyliczającą od razu kilka podstawowych charakterystyk wektora jest summary().
> w = c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.1, 11.11, 12.12, 13.13, 14.14, 15.15) > summary(w) Min. 1st Qu. Median Mean 3rd Qu. Max. 1.10 4.95 8.80 8.35 11.61 15.15 |
Wynikiem działania funkcji summary() jest 6-elementowy wektor z podstawowymi charakterystykami statystycznymi wektora: minimum, pierwszy kwartyl (kwantyl rzedu 0.25), mediana, średnia, 3 kwartyl (kwantyl rzedu 0.75) i maksimum.
Funkcje na wektorach tekstowych
Typ wektora zależy od typu jego wyrazów. Badamy go używając funkcji mode(), typeof(), class() lub str().
> w1=as.integer(c(1,2,3,4)) > w2=c(1.0,2.0,3.1,4.1) > w3=c("1", "2", "3", "a") > mode(w1); mode(w2); mode(w3) [1] "numeric" [1] "numeric" [1] "character" > typeof(w1); typeof(w2); typeof(w3) [1] "integer" [1] "double" [1] "character" > class(w1); class(w2); class(w3) [1] "integer" [1] "numeric" [1] "character" > str(w1); str(w2); str(w3) int [1:4] 1 2 3 4 num [1:4] 1 2 3.1 4.1 chr [1:4] "1" "2" "3" "a" |
Wektory tekstowe można w różny sposób przetwarzać za pomocą funkcji działających na indeksach i funkcji logicznych, podobnie jak wektory liczbowe. Pokazano to na przykładzie ciągu tekstowego (oznaczeń płci “f” (samica), “m” samiec, “o” obojnak).
> ciag=c("f","f","m","o","o","f","m","m","f","o") > ciag [1] "f" "f" "m" "o" "o" "f" "m" "m" "f" "o" > dobre = ciag=="f" > dobre [1] TRUE TRUE FALSE FALSE FALSE TRUE FALSE FALSE TRUE FALSE > ciag[dobre] [1] "f" "f" "f" "f" > ciag[ciag=="f"] [1] "f" "f" "f" "f" > length(ciag[ciag=="f"]) [1] 4 > ciag=="f" | ciag=="o" [1] TRUE TRUE FALSE TRUE TRUE TRUE FALSE FALSE TRUE TRUE > ciag[ciag=="f" | ciag=="o"] [1] "f" "f" "o" "o" "f" "f" "o" > length(ciag[ciag=="f" | ciag=="o"]) [1] 7 |
Ponadto na wektorach tekstowych działają następujące funkcje:
- length() liczba elementów wektora,
- min() pierwszy w kolejności alfabetycznej wyraz tekstowy,
- min() ostatni w kolejności alfabetycznej wyraz tekstowy,
- rev() ciąg zapisany w odwrotnej kolejności,
- sort() ciąg w kolejności alfabetycznej,
- order() numery wyrazów elementów w wektorze po uporządkowaniu ich w kolejności alfabetycznej,
- rank() numery wyrazów po uporządkowaniu ich w kolejności alfabetycznej, przy czym takie same wyrazy mają rangę równą średniej arytmetycznej numerów kolejności, które na nie przypadają.
> wek=c("Ala", "Ola", "Ela", "Ula", "Iza", "Ewa", "Ala" ) > length(wek) [1] 7 > min(wek) [1] "Ala" > rev(wek) [1] "Ala" "Ewa" "Iza" "Ula" "Ela" "Ola" "Ala" > sort(wek) [1] "Ala" "Ala" "Ela" "Ewa" "Iza" "Ola" "Ula" > order(wek) [1] 1 7 3 6 5 2 4 > rank(wek) [1] 1.5 6.0 3.0 7.0 5.0 4.0 1.5 |
Za pomocą operatora == wektory tekstowe można porównywać pod względem identyczności wyrazów (czyli na którym miejscu w obu wektorach są takie same teksty), przy czym zgodnie z ogólnymi zasadami R, krótszy wektor jest wydłużany poprzez wielokrotne powielanie go. Natomiast operator %in% powoduje sprawdzenie czy kolejne wyrazy wektora z lewej strony są równe któremukolwiek wyrazowi wektora z prawej strony.
> weka=c("a", "b", "c") > wekb=c("a", "a", "b", "b", "c", "c", "d") > weka==wekb [1] TRUE FALSE FALSE FALSE FALSE TRUE FALSE Komunikat ostrzegawczy: W poleceniu 'a == wekb': długość dłuszego obiektu nie jest wielokrotnością długości krótszego obiektu > weka %in% wekb [1] TRUE TRUE TRUE > wekb %in% weka [1] TRUE TRUE TRUE TRUE TRUE TRUE FALSE |
W rozdziale pokazującym działania na znakach i tekstach omówiono funkcję paste() sklejającą kilka tekstów w jeden. Nie działa ona na wektorze tekstów gdy jest wywołana bez opcji collapse=”. Operacja odwrotna do tej funkcji: strsplit() omówiona jest w rozdziale Listy.
> # funkcja paste() > paste("Ala", "Ola", "Ela", "Ula", sep=", ") [1] "Ala, Ola, Ela, Ula" > ciag=c("Ala", "Ola", "Ela", "Ula") > paste(ciag) [1] "Ala" "Ola" "Ela" "Ula" > paste(ciag, sep='') [1] "Ala" "Ola" "Ela" "Ula" > paste(ciag, collapse='') [1] "AlaOlaElaUla" > paste(ciag, collapse='; ') [1] "Ala; Ola; Ela; Ula" |
Najczęściej jednak funkcja paste() służy do automatycznego numerowanych wektorów testowych. Jest to przy opisie wyników, projektowaniu nagłówków itp. bardzo przydatna możliwość.
> paste("miesiąc",1:12) [1] "miesiąc 1" "miesiąc 2" "miesiąc 3" "miesiąc 4" "miesiąc 5" "miesiąc 6" "miesiąc 7" [8] "miesiąc 8" "miesiąc 9" "miesiąc 10" "miesiąc 11" "miesiąc 12" > paste(letters,1:26, sep="") [1] "a1" "b2" "c3" "d4" "e5" "f6" "g7" "h8" "i9" "j10" "k11" "l12" "m13" "n14" "o15" [16] "p16" "q17" "r18" "s19" "t20" "u21" "v22" "w23" "x24" "y25" "z26" |
Funkcja substring() z opcjami n1= (pierwszy znak podtekstu) i n2= (ostatni znak podtekstu) gdy zastosujemy ciągi zamiast pojedynczych liczb, utworzy wektor fragmentów tekstu lub ciąg znaków.
> substring("statystyka",1:10,10) [1] "statystyka" "tatystyka" "atystyka" "tystyka" "ystyka" [6] "styka" "tyka" "yka" "ka" "a" > substring("statystyka",1,1:10) [1] "s" "st" "sta" "stat" "staty" [6] "statys" "statyst" "statysty" "statystyk" "statystyka" > substring("statystyka",1:10,1:10) [1] "s" "t" "a" "t" "y" "s" "t" "y" "k" "a" |
Funkcja tekstowa grepl() pozwalająca na sprawdzenie czy dany tekst zawiera się w innym dłuższym tekście również może działać na wektorze tekstowym i sprawdzać, w których tekstach zawiera się pierwszy tekst.
> c=c('abdjy','skahtd','abdtsfe','asba','cxwqab') > grepl('ab',c) [1] TRUE FALSE TRUE FALSE TRUE |
Funkcje zmieniające wektor liczbowy na tekstowy i odwrotnie
Zamiana liczb na tekst następuje po zastosowaniu funkcji as.character(), którą można zastosować dla dowolnego wektora liczbowego. Funkcja do niej odwrotna as.numeric() zamienia teksty mające postać liczb nma liczby.
> x=c(10.28, 8.64, 5.67, 10.41, 6.20, 8.07, 7.90, 5.33, 8.12, 6.39, 6.71, 6.13) > as.character(x) [1] "10.28" "8.64" "5.67" "10.41" "6.2" "8.07" "7.9" "5.33" "8.12" "6.39" "6.71" "6.13" > c=c("10.28", "Ala", "5.67", "10.41", "ma", "8.07", "7.9", "5.33", "8.12", "kota", "6.71", "6.13") > as.numeric(c) [1] 10.28 NA 5.67 10.41 NA 8.07 7.90 5.33 8.12 NA 6.71 6.13 Komunikat ostrzegawczy: pojawiły się wartości NA na skutek przekształcenia |
Do zamiany wektora liczbowego na tekstowy można też użyć funkcji paste().
> x=c(10.28, 8.64, 5.67, 10.41, 6.20, 8.07, 7.90, 5.33, 8.12, 6.39, 6.71, 6.13) > paste(x) [1] "10.28" "8.64" "5.67" "10.41" "6.2" "8.07" "7.9" "5.33" "8.12" "6.39" "6.71" "6.13" > paste(1:10) [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" |
Wartość nieokreślona i pomijalna w wektorze
W rozdziale o procedurach stosowanych dla liczb pokazano, że pewne działania (dzielenie zera przez zero; różnica Inf – Inf) generują wynik NaN. Jest to wartość nieokreślona. Gdy wyniki pewnej funkcji zapisujemy w ciągu, to mogą się tam pojawić elementy NaN. Dla takiego ciągu nie da się wyliczyć funkcji statystycznych.
> x = 1:9 - 5 > x [1] -4 -3 -2 -1 0 1 2 3 4 > y = 9:1-5 > y [1] 4 3 2 1 0 -1 -2 -3 -4 > x/y [1] -1 -1 -1 -1 NaN -1 -1 -1 -1 > mean(x/y) [1] NaN |
Czasem w ciągu wyników jakiegoś doświadczenia trzeba umieścić wartość, która w obliczeniach statystycznych będzie pomijana. Robi się to w przypadku gdy wyniku tego z różnych powodów nie ma, co wcale nie oznacza, że taki doświadczenie ma wynik np. równy 0 lub nieokreślony. Może w tym czasie aparatura odczytująca ten wynik zepsuła się, może trzeba go było odrzucić jako niewiarygodny, może próbka zaginęła lub zniszczyła po wykonaniu innych eksperymentów, z których nie należy rezygnować. W bazach danych wstawia się w to miejsce wartość pomijalną. Może to być puste miejsce (w Excelu, Accessie), kropka (w SASie), liczba -32768 (w Statgrafie), zestaw liter “MISS” (w programie sx). W R jest to zestaw dwóch liter NA. Mogą zastępować zarówno liczby jak i symbole.
Wartość pomijalna NA, podobnie jak NaN, uniemożliwia wykonanie niektórych funkcji statystycznych.
> x=c(-1,0,2,-1,NaN,0,NA) > length(x) [1] 7 > mean(x) [1] NaN > x=c(-1,0,2,-1,0,NA) > mean(x) [1] NA |
Wartość pomijalna NA w R nie jest traktowana zatem tak samo jak wartość pomijalna w programach Excel, Access, SAS itd. W tamtych programach po prostu jest pomijana i wszelkie funkcje statystyczne są wykonywane na odpowiednio krótszym ciągu. Aby w R wykonywać obliczenia statystyczne na ciągach zawierających NA lub NaN należy użyć funkcji is.na() generującej ciąg wartości logicznych TRUE lub FALSE w zależności od tego czy odpowiada mu wartość NA lub NaN w ciągu użytym jako argument.
> x=c(-1,0,2,3,NA,0,NA,-1,NaN) > is.na(x) [1] FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE TRUE > !is.na(x) [1] TRUE TRUE TRUE TRUE FALSE TRUE FALSE TRUE FALSE > x[!is.na(x)] [1] -1 0 2 3 0 -1 > sum(x[!is.na(x)]) [1] 3 |
Takie funkcje jak sum(), prod(), mean(), var(), sd(), min(), max() i range() wykonywane na wektorach, w których są wartości nieokreślone lub pomijalne wymagają użycia formuł:
sum(nazwa_wektora[!is.na(nazwa_wektora)])
prod(nazwa_wektora[!is.na(nazwa_wektora)])
mean(nazwa_wektora[!is.na(nazwa_wektora)])
var(nazwa_wektora[!is.na(nazwa_wektora)])
sd(nazwa_wektora[!is.na(nazwa_wektora)])
min(nazwa_wektora[!is.na(nazwa_wektora)])
max(nazwa_wektora[!is.na(nazwa_wektora)])
range(nazwa_wektora[!is.na(nazwa_wektora)])
Co ciekawe, nie dotyczy to funkcji which.min() i which.max().