Podstawowym typem danych w R jest wektor, który jest uporządkowanym zbiorem wartości. Pierwszą rzeczą, którą powinieneś wiedzieć, jest to, że w przeciwieństwie do innych języków, pojedyncze wartości liczb, ciągów i logiki są specjalnymi przypadkami wektorów (wektorów o długości jeden), co oznacza, że nie ma pojęcia skalarów w R. -wymiarowa struktura danych i wszystkie jej elementy są tego samego typu danych. Najprostszym sposobem utworzenia wektora jest użycie funkcji c(), która oznacza kombinację i przekształca wszystkie argumenty w jeden typ. Przymus przejdzie od prostszych do bardziej złożonych typów. To znaczy, jeśli utworzymy wektor zawierający logiki, liczby, oraz znaki, jak pokazuje poniższy przykład, nasz wynikowy wektor będzie zawierał tylko znaki, które są bardziej złożone z trzech typów. Jeśli utworzymy wektor zawierający wartości logiczne i numeryczne, nasz wynikowy wektor będzie numeryczny, ponownie, ponieważ jest to typ bardziej złożony. Wektory można nazwać lub nie. Dostęp do nienazwanych elementów wektorów można uzyskać tylko poprzez odniesienia pozycyjne, natomiast do nazwanych wektorów można uzyskać dostęp za pośrednictwem odniesień pozycyjnych, jak również odniesień do nazw. W poniższym przykładzie wektor y jest wektorem nazwanym, w którym każdy element jest nazwany literą od A do I. Oznacza to, że w przypadku x mamy dostęp do elementów tylko za pomocą ich pozycji (pierwsza pozycja jest traktowana jako 1 zamiast 0 używanego w innych językach), ale w przypadku y możemy również użyć przypisanych nam nazw. Zauważ również, że specjalne wartości, o których wspomnieliśmy wcześniej, czyli NA, NULL, NaN i Inf, zostaną przekształcone w znaki, jeśli jest to typ bardziej złożony, z wyjątkiem NA, który pozostaje taki sam. W przypadku, gdy wymuszenie dotyczy liczb, wszystkie pozostają takie same, ponieważ są prawidłowymi wartościami liczbowymi. Wreszcie, jeśli chcemy poznać długość wektora, po prostu wywołaj na nim funkcję length :
x <- c(TRUE, FALSE, -1,0,1,”A”, „B”, NA, NULL, NaN, Inf
x
#> [1] “TRUE” “FALSE” “-1” “0” “1” “A” “B” NA
#> [9] “NaN” “Inf”
x[1]
#> [1] „TRUE”
x[5]
#> [1] “1”
Y <- c(A=TRUE, B= FALSE, C= -1, D= 0, E = 1, F = NA, G = NULL, H =NaN, I = Inf)
y
#> A B C D E F H I.
#> 1 0-1 0 1 ND NaN Inf
y[1]
#> A
#> 1
y[„A”]
#> A
#> 1
y[5]
#> E.
#> 1
y[„E”]
#> E.
#> 1
legth(x)
#> [1] 10
legth(y)
#> [1] 8
Ponadto możemy wybierać zbiory lub zakresy elementów za pomocą wektorów z numerami indeksu dla wartości, które chcemy pobrać. Na przykład użycie selektora c (1, 2) zwróci pierwsze dwa elementy wektora, podczas gdy użycie c (1, 3, 5) zwróci pierwszy, trzeci i piąty element. Funkcja: (tak, jest to funkcja, mimo że zwykle nie używamy składni podobnej do funkcji, którą widzieliśmy do tej pory w innych przykładach, aby ją wywołać), jest często używana jako skrót do tworzenia selektorów zakresu. Na przykład składnia 1: 5 oznacza, że chcemy mieć wektor z elementami od 1 do 5, co byłoby równoważne jawnemu użyciu c (1, 2, 3, 4, 5). Ponadto, jeśli wyślemy wektor logiki, który musi mieć taką samą długość jak wektor, z którego chcemy pobrać wartości, każda z wartości logicznych zostanie powiązana z odpowiadającą pozycją w wektorze, z którego chcemy pobrać, i jeśli odpowiadająca mu logika to TRUE, wartość zostanie pobrana, ale jeśli jest FALSE, nie będzie. Poniższy przykład przedstawia wszystkie te metody wyboru:
x[c(1,2,3,4,5)]
#> [1] “TRUE” “FALSE” “-1” “0” “1”
X[1:5]
#> [1] “TRUE” “FALSE” “-1” “0” “1”
x[c(1,3,50]
#> [1] “TRUE” “-1” “1”
X[c(TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE)]
#> [1] “TRUE” “-1” “1” “B” “NaN” NA
Następnie porozmawiamy o operacjach między wektorami. W przypadku wektorów numerycznych możemy zastosować operacje element do elementu, używając po prostu operatorów, tak jak zwykle. W tym przypadku R dopasuje elementy dwóch wektorów parami i zwróci wektor. Poniższy przykład pokazuje, jak dwa wektory są dodawane, odejmowane, mnożone i dzielone w sposób od elementu do elementu. Ponadto, ponieważ pracujemy z wektorami o tej samej długości, możemy chcieć uzyskać ich iloczyn skalarny, co możemy zrobić za pomocą operatora %*% który wykonuje mnożenie macierzowe, w tym przypadku wektor do wektora:
x <- c (1,2,3,4)
y <- c (5,6,7,8)
x + y
#> [1] 6 8 10 12
x-y
#> [1] -4 -4 -4 -4
x*y
#> [1] 5 12 21 32
x/y
#> [1] 0,2000 0,3333 0,4286 0,5000
x %*% y
#> [, 1]
#> [1,] 70
Jeśli chcesz połączyć wiele wektorów w jeden, możesz po prostu użyć na nich c() rekurencyjnie, a to automatycznie je spłaszczy. Powiedzmy, że chcemy połączyć x i y w z tak, aby elementy y pojawiały się jako pierwsze. Ponadto załóżmy, że po tym jak chcemy je posortować, więc stosujemy funkcję sort() na z:
z <- c(y,x)
z
#> [1] 5 6 7 8 1 2 3 4
sort(z)
#> [1] 1 2 3 4 5 6 7 8
Częstym źródłem nieporozumień jest sposób, w jaki R radzi sobie z wektorami o różnych długościach. Jeśli zastosujemy operację element-element, tak jak te, które omówiliśmy wcześniej, ale używając wektorów o różnych długościach, możemy spodziewać się, że R zgłosi błąd, tak jak ma to miejsce w innych językach. Jednak tak nie jest. Zamiast tego powtarza elementy wektorowe w kolejności, dopóki wszystkie nie będą miały tej samej długości. Poniższy przykład przedstawia trzy wektory, każdy o innej długości, oraz wynik ich dodania. Sposób, w jaki domyślnie skonfigurowano R, faktycznie otrzymasz komunikat ostrzegawczy, aby poinformować Cię, że wektory, na których operowałeś, nie miały tej samej długości, ale ponieważ R można skonfigurować tak, aby uniknąć wyświetlania ostrzeżeń, nie powinieneś na nich polegać:
c(1,2) + c(3,4,5) + c(6,7,8,9)
#> Ostrzeżenie w c (1, 2) + c (3, 4, 5):
dłuższa długość obiektu nie jest wielokrotnością
#> krótsza długość obiektu
#> Ostrzeżenie w c (1, 2) + c (3, 4, 5) + c (6, 7, 8, 9):
dłuższa długość obiektu to
#> nie jest wielokrotnością krótszej długości obiektu
#> [1] 10 13 14 13
Pierwszą rzeczą, która może przyjść na myśl, jest to, że pierwszy wektor jest rozszerzany do c(1,2,1,2), drugi wektor jest rozszerzany do c(3,4,5,3) i trzecia jest zachowana bez zmian, ponieważ jest największa. Jeśli dodamy do siebie te wektory, otrzymamy wynik c(10,13,14,14). Jednak, jak widać na przykładzie, wynik w rzeczywistości to c(10,13,14,13). Więc czego nam brakuje? Źródłem nieporozumień jest to, że R robi to krok po kroku, co oznacza, że najpierw wykona dodawanie c(1,2) + c(3,4,5), które po rozwinięciu jest c(1,2,1) + c(3,4,5) i daje w wyniku c(4,6,6), a następnie biorąc pod uwagę ten wynik, następny krok, który wykonuje R. to c(4,6,6) + c(6,7,8,9), które po rozwinięciu to c(4,6,6,4) + c(6,7,8,9) i stąd pochodzi wynik, jaki otrzymujemy. Na początku może to być mylące, ale pamiętaj tylko, aby wyobrazić sobie operacje krok po kroku. Na koniec krótko wspomnimy o bardzo potężnej funkcji języka R, znanej jako wektoryzacja. Wektoryzacja oznacza, że wykonujesz operację na wektorze od razu, zamiast niezależnie robić to na każdym z jego elementów. Jest to funkcja, którą powinieneś dość dobrze poznać. Programowanie bez tego jest uważane za zły kod R i to nie tylko ze względów składniowych, ale także dlatego, że kod wektorowy wykorzystuje wiele wewnętrznych optymalizacji w R, co skutkuje znacznie szybszym kodem. Mimo że kod zwektoryzowany na początku może wydawać się przerażający lub magiczny, w rzeczywistości R sprawia, że w niektórych przypadkach jest dość prosty do wdrożenia. Na przykład, możemy podnieść do kwadratu każdy z elementów w wektorze x, używając symbolu x, tak jakby to była pojedyncza liczba. R jest wystarczająco inteligentny, aby zrozumieć, że chcemy zastosować operację do każdego elementu wektora. Wiele funkcji w R można zastosować za pomocą tej techniki:
x^2
#> [1] 1 4 9 16
Zobaczymy więcej przykładów, które naprawdę pokazują, jak wektoryzacja może świecić w następnej sekcji o funkcjach, gdzie zobaczymy, jak stosować operacje wektoryzowane, nawet jeśli operacje zależą od innych parametrów.