Wstęp do analizy

Cel analizy

Przedmiotem analizy są dane kredytowe obejmujące zbiór informacji o 1000 osób, na podstawie których zostały one zaklasyfikowane jako ryzykowne lub nie pod względem możliwości spłaty przez nie zaciągniętego kredytu. Zbiór obejmuje informacje dotyczące 20 zmiennych (V1 - V20) opisujących kredytobiorcę. Wśród zmiennych znalazły się zmienne jakościowe i ilościowe. Zmienna “odpowiedź” (V21) w zbiorze danych odpowiada etykiecie ryzyka, zgodnie z przyjętym prze autora sposobem kodowania:

  • 1 oznacza kredyt “zły”,
  • 2 oznacza kredyt dobry.

Informacje na temat poszczególnych zmiennych można znaleźć na stronie:(https://archive.ics.uci.edu/ml/datasets/statlog+(german+credit+data).

credit <- read.table("http://archive.ics.uci.edu/ml/machine-learning-databases/statlog/german/german.data")
print(head(credit))
##    V1 V2  V3  V4   V5  V6  V7 V8  V9  V10 V11  V12 V13  V14  V15 V16  V17 V18
## 1 A11  6 A34 A43 1169 A65 A75  4 A93 A101   4 A121  67 A143 A152   2 A173   1
## 2 A12 48 A32 A43 5951 A61 A73  2 A92 A101   2 A121  22 A143 A152   1 A173   1
## 3 A14 12 A34 A46 2096 A61 A74  2 A93 A101   3 A121  49 A143 A152   1 A172   2
## 4 A11 42 A32 A42 7882 A61 A74  2 A93 A103   4 A122  45 A143 A153   1 A173   2
## 5 A11 24 A33 A40 4870 A61 A73  3 A93 A101   4 A124  53 A143 A153   2 A173   2
## 6 A14 36 A32 A46 9055 A65 A73  2 A93 A101   4 A124  35 A143 A153   1 A172   2
##    V19  V20 V21
## 1 A192 A201   1
## 2 A191 A201   2
## 3 A191 A201   1
## 4 A191 A201   1
## 5 A191 A201   2
## 6 A192 A201   1

Informacja dotycząca sposobu nawigacji w obiektach typu data frame w R:

  • aby wywołać wybrane wiersze i kolumny z obiektu data frame należy podać nazwę obiektu oraz w nawiasie kwadratowym numer wybranego wiersza i numer wybranej kolumny,
  • przykładowo fragment kodu credit[3,5] spowoduje wyświetlenie w konsoli wartości znajdującej się w 3 wierszu i 5 kolumnie obiektu credit,
  • chcąc wywołać wszystkie wartości z danej kolumny/wiersza w powyższym kodzie należy opuścić numer kolumny/wiersza - np. kod credit[,5] spowoduje wywołanie wszystkich wierszy z 5 kolumny, natomiast kod credit[3,] wywoła wartości wszystkich kolumn dla 3 wiersza,
  • alternatywnie wartości dla danej kolumny można wywołać poprzez kod w ogólnej postaci obiekt$nazwa_kolumny - np. kod credit$V1 spowoduje wyświetlenie wszystkich wartości z kolumny o nazwie V1,
  • zastosowanie kodu: credit[2:3, 5:8] spowoduje wyświetlenie wartości z 2 i 3 wiersza oraz z 5, 6, 7 i 8 kolumny,
  • chcąc wywołać wartości z kilku kolumn/wierszy, które nie są obok siebie należy numery kolumn/wierszy podać w postaci wektora zapisywanego jako c(numery wybranych wierszy/kolumn) - przykładowo kod credit[c(2,4,6), c(11, 15)] wskazuje na wartości które znajdują się w 2, 4 i 6 wierszu oraz 11 i 15 kolumnie.
credit[c(2,4,6), c(11, 15)]
##   V11  V15
## 2   2 A152
## 4   4 A153
## 6   4 A153

Zapoznanie się z danymi

Ogólne informacje na temat obiektu można użyskać poprzez wywołanie funkcji str - structure. w podsumowaniu:

  • uzyskujemy informację dotyczącą liczby obserwacji i liczby zmiennych,
  • nazwy kolejnych zmiennych,
  • typu danej zmiennej,
  • kilku pierwszych wartości danej zmiennej.

Na temat typu danych w R można przeczytać na stronie

str(credit)
## 'data.frame':    1000 obs. of  21 variables:
##  $ V1 : chr  "A11" "A12" "A14" "A11" ...
##  $ V2 : int  6 48 12 42 24 36 24 36 12 30 ...
##  $ V3 : chr  "A34" "A32" "A34" "A32" ...
##  $ V4 : chr  "A43" "A43" "A46" "A42" ...
##  $ V5 : int  1169 5951 2096 7882 4870 9055 2835 6948 3059 5234 ...
##  $ V6 : chr  "A65" "A61" "A61" "A61" ...
##  $ V7 : chr  "A75" "A73" "A74" "A74" ...
##  $ V8 : int  4 2 2 2 3 2 3 2 2 4 ...
##  $ V9 : chr  "A93" "A92" "A93" "A93" ...
##  $ V10: chr  "A101" "A101" "A101" "A103" ...
##  $ V11: int  4 2 3 4 4 4 4 2 4 2 ...
##  $ V12: chr  "A121" "A121" "A121" "A122" ...
##  $ V13: int  67 22 49 45 53 35 53 35 61 28 ...
##  $ V14: chr  "A143" "A143" "A143" "A143" ...
##  $ V15: chr  "A152" "A152" "A152" "A153" ...
##  $ V16: int  2 1 1 1 2 1 1 1 1 2 ...
##  $ V17: chr  "A173" "A173" "A172" "A173" ...
##  $ V18: int  1 1 2 2 2 2 1 1 1 1 ...
##  $ V19: chr  "A192" "A191" "A191" "A191" ...
##  $ V20: chr  "A201" "A201" "A201" "A201" ...
##  $ V21: int  1 2 1 1 2 1 1 1 1 2 ...

Kolejnym etapem zapoznania się z danymi jest sprawdzenie, czy obiekcie znajdują się pola bez wskazanej w nich wartości. Tego typu obszary oznaczane są jako Not Available. Do sprawdzenia pól bez wartości można wykorzystać kod is.na(nazwa_obiektu). Jako wynik funkcji otrzymuje się obiekt typu logicznego z wartościami TRUE jeśli w danym obszarze brak jest wartości, lub FALSE jeśli w obszarze znajdują się wartości. W przypadku większych obiektów do sprawdzenia kompletności danych można wykorzystać funkcję colSums(is.na(nazwa obiektu)) która podaje sumę kolumn po ich zamianie na wartości logiczne. Jeśli we wszystkich kolumnach znajdują się wartości (funkcja is.na() daje wynik FALSE) suma kolumn bedzie równa 0.

colSums(is.na(credit))
##  V1  V2  V3  V4  V5  V6  V7  V8  V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20 
##   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 
## V21 
##   0

Najważniejsze informacje dotyczące obiektu można uzyskać poprzez funkcję summary(nazwa_obiektu). W przypadku obiektu typu data frame dla zmiennych ilościowych funkcja podaje wartości statystyk, a dla zmiennych jakościowych udział poszczególnych wartości zmiennych.

summary(credit)
##       V1                  V2            V3                 V4           
##  Length:1000        Min.   : 4.0   Length:1000        Length:1000       
##  Class :character   1st Qu.:12.0   Class :character   Class :character  
##  Mode  :character   Median :18.0   Mode  :character   Mode  :character  
##                     Mean   :20.9                                        
##                     3rd Qu.:24.0                                        
##                     Max.   :72.0                                        
##        V5             V6                 V7                  V8       
##  Min.   :  250   Length:1000        Length:1000        Min.   :1.000  
##  1st Qu.: 1366   Class :character   Class :character   1st Qu.:2.000  
##  Median : 2320   Mode  :character   Mode  :character   Median :3.000  
##  Mean   : 3271                                         Mean   :2.973  
##  3rd Qu.: 3972                                         3rd Qu.:4.000  
##  Max.   :18424                                         Max.   :4.000  
##       V9                V10                 V11            V12           
##  Length:1000        Length:1000        Min.   :1.000   Length:1000       
##  Class :character   Class :character   1st Qu.:2.000   Class :character  
##  Mode  :character   Mode  :character   Median :3.000   Mode  :character  
##                                        Mean   :2.845                     
##                                        3rd Qu.:4.000                     
##                                        Max.   :4.000                     
##       V13            V14                V15                 V16       
##  Min.   :19.00   Length:1000        Length:1000        Min.   :1.000  
##  1st Qu.:27.00   Class :character   Class :character   1st Qu.:1.000  
##  Median :33.00   Mode  :character   Mode  :character   Median :1.000  
##  Mean   :35.55                                         Mean   :1.407  
##  3rd Qu.:42.00                                         3rd Qu.:2.000  
##  Max.   :75.00                                         Max.   :4.000  
##      V17                 V18            V19                V20           
##  Length:1000        Min.   :1.000   Length:1000        Length:1000       
##  Class :character   1st Qu.:1.000   Class :character   Class :character  
##  Mode  :character   Median :1.000   Mode  :character   Mode  :character  
##                     Mean   :1.155                                        
##                     3rd Qu.:1.000                                        
##                     Max.   :2.000                                        
##       V21     
##  Min.   :1.0  
##  1st Qu.:1.0  
##  Median :1.0  
##  Mean   :1.3  
##  3rd Qu.:2.0  
##  Max.   :2.0

w przypadku zmiennej typu chr funkcja summary podaje tylko długość ciągu. W analizie statystycznej często wykorzystywanym typem zmiennych jest factor. Zamiana zmiennej/obiektu na inny typ możliwy jest za pomocą funkcji as. .... Przykładowo funkcja as.factor() zamieni inny typ zmiennych na zmienną typu factor.

Według przyjętego sposobu kodowania dla zmiennej V21 wartość 1 - oznacza “zły” kredyt, zaś 2 - “dobry”. Bardziej naturalnym sposobem kodowania jest oznaczenie jako 0 - “złych” kredytów, zaś jako 1 - “dobrych”. Z tego też względu od wartości z kolumny V21 odejmujemy 1 aby otrzymać z jedynki - zero, a z dwójki - jedynkę.

Po przekształceniach otrzymuje się następujące wyniki dla funkcji str() oraz summary().

credit$V21<-credit$V21-1

names<-c(1,3,4,6,7,9,10,12,14,15,17,19,20)

credit[,names]<- lapply(credit[,names], factor)

credit$V21<-as.factor(credit$V21)

str(credit)
## 'data.frame':    1000 obs. of  21 variables:
##  $ V1 : Factor w/ 4 levels "A11","A12","A13",..: 1 2 4 1 1 4 4 2 4 2 ...
##  $ V2 : int  6 48 12 42 24 36 24 36 12 30 ...
##  $ V3 : Factor w/ 5 levels "A30","A31","A32",..: 5 3 5 3 4 3 3 3 3 5 ...
##  $ V4 : Factor w/ 10 levels "A40","A41","A410",..: 5 5 8 4 1 8 4 2 5 1 ...
##  $ V5 : int  1169 5951 2096 7882 4870 9055 2835 6948 3059 5234 ...
##  $ V6 : Factor w/ 5 levels "A61","A62","A63",..: 5 1 1 1 1 5 3 1 4 1 ...
##  $ V7 : Factor w/ 5 levels "A71","A72","A73",..: 5 3 4 4 3 3 5 3 4 1 ...
##  $ V8 : int  4 2 2 2 3 2 3 2 2 4 ...
##  $ V9 : Factor w/ 4 levels "A91","A92","A93",..: 3 2 3 3 3 3 3 3 1 4 ...
##  $ V10: Factor w/ 3 levels "A101","A102",..: 1 1 1 3 1 1 1 1 1 1 ...
##  $ V11: int  4 2 3 4 4 4 4 2 4 2 ...
##  $ V12: Factor w/ 4 levels "A121","A122",..: 1 1 1 2 4 4 2 3 1 3 ...
##  $ V13: int  67 22 49 45 53 35 53 35 61 28 ...
##  $ V14: Factor w/ 3 levels "A141","A142",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ V15: Factor w/ 3 levels "A151","A152",..: 2 2 2 3 3 3 2 1 2 2 ...
##  $ V16: int  2 1 1 1 2 1 1 1 1 2 ...
##  $ V17: Factor w/ 4 levels "A171","A172",..: 3 3 2 3 3 2 3 4 2 4 ...
##  $ V18: int  1 1 2 2 2 2 1 1 1 1 ...
##  $ V19: Factor w/ 2 levels "A191","A192": 2 1 1 1 1 2 1 2 1 1 ...
##  $ V20: Factor w/ 2 levels "A201","A202": 1 1 1 1 1 1 1 1 1 1 ...
##  $ V21: Factor w/ 2 levels "0","1": 1 2 1 1 2 1 1 1 1 2 ...
summary(credit)
##    V1            V2         V3            V4            V5          V6     
##  A11:274   Min.   : 4.0   A30: 40   A43    :280   Min.   :  250   A61:603  
##  A12:269   1st Qu.:12.0   A31: 49   A40    :234   1st Qu.: 1366   A62:103  
##  A13: 63   Median :18.0   A32:530   A42    :181   Median : 2320   A63: 63  
##  A14:394   Mean   :20.9   A33: 88   A41    :103   Mean   : 3271   A64: 48  
##            3rd Qu.:24.0   A34:293   A49    : 97   3rd Qu.: 3972   A65:183  
##            Max.   :72.0             A46    : 50   Max.   :18424            
##                                     (Other): 55                            
##    V7            V8          V9        V10           V11          V12     
##  A71: 62   Min.   :1.000   A91: 50   A101:907   Min.   :1.000   A121:282  
##  A72:172   1st Qu.:2.000   A92:310   A102: 41   1st Qu.:2.000   A122:232  
##  A73:339   Median :3.000   A93:548   A103: 52   Median :3.000   A123:332  
##  A74:174   Mean   :2.973   A94: 92              Mean   :2.845   A124:154  
##  A75:253   3rd Qu.:4.000                        3rd Qu.:4.000             
##            Max.   :4.000                        Max.   :4.000             
##                                                                           
##       V13          V14        V15           V16          V17     
##  Min.   :19.00   A141:139   A151:179   Min.   :1.000   A171: 22  
##  1st Qu.:27.00   A142: 47   A152:713   1st Qu.:1.000   A172:200  
##  Median :33.00   A143:814   A153:108   Median :1.000   A173:630  
##  Mean   :35.55                         Mean   :1.407   A174:148  
##  3rd Qu.:42.00                         3rd Qu.:2.000             
##  Max.   :75.00                         Max.   :4.000             
##                                                                  
##       V18          V19        V20      V21    
##  Min.   :1.000   A191:596   A201:963   0:700  
##  1st Qu.:1.000   A192:404   A202: 37   1:300  
##  Median :1.000                                
##  Mean   :1.155                                
##  3rd Qu.:1.000                                
##  Max.   :2.000                                
## 

Odkodowanie zmiennych

Ciąg wywoływanych funkcji spowoduje, iż finalnie otrzymujemy zestaw odkodowanych zmiennych ilościowych i jakościowych, które opisują cechy osób obiegających się o kredyt. Część zmiennych jakościowych to zmienne wyrażone w skali nominalnej, inne zaś - w skali porzadkowej.

credit$V1<-ifelse(credit$V1 == "A11", "< 0", ifelse(credit$V1 == "A12", "0-200", ifelse(credit$V1 == "A13", ">200", "brak")))

credit$V3<-ifelse(credit$V3 == "A30", "brak", ifelse(credit$V3 == "A31", "wszystkie_spł", ifelse(credit$V3 == "A32", "istniejace_spł",
                    ifelse(credit$V3 == "A33", "opoznienia", "krytyczne"))))

credit$V4<-ifelse(credit$V4 == "A40", "sam_nowy", ifelse(credit$V4 == "A41", "sam_uzyw", 
            ifelse(credit$V4 == "A42", "meble", ifelse(credit$V4 == "A43", "RTV",
            ifelse(credit$V4 == "A44", "AGD", ifelse(credit$V4== "A45", "remont", 
            ifelse(credit$V4== "A46", "edukacja", ifelse(credit$V4 == "A47", "wakacje",
             ifelse(credit$V4== "A48", "przekwalifikowanie", ifelse(credit$V4 == "A49", "biznes", "inne"))                                                                                        ))))
       ))))


credit$V6<-ifelse(credit$V6 == "A61", "<100", ifelse(credit$V6 == "A62", "100-500", ifelse(credit$V6 == "A63", "500-1000",
              ifelse(credit$V6 == "A64", ">1000", "brak"))))

credit$V7<-ifelse(credit$V7 == "A71", "bezrobotny", ifelse(credit$V7 == "A72", "<1 rok", 
                     ifelse(credit$V7 == "A73", "1-4",
              ifelse(credit$V7 == "A74", "4-7", ">7"))))

credit$V9<-ifelse(credit$V9 == "A92", "K", "M")

credit$V10 <-ifelse(credit$V10 == "A101", "brak", "tak")

credit$V12<-ifelse(credit$V12 == "A121", "nieruchomosc", 
                   ifelse(credit$V12 == "A122", "ubezpieczenie", 
                          ifelse(credit$V12 == "A123", "samochod", "brak")))

credit$V14<-ifelse(credit$V14 == "A141", "bank", ifelse(credit$V14 == "A142", "sklep", "brak"))

credit$V15 <-ifelse(credit$V15 == "A151", "czynsz", ifelse(credit$V15 == "A152", "wlasne", "za_darmo"))

credit$V17 <-ifelse(credit$V17 == "A171", "niewykwal_nierez", 
                    ifelse(credit$V17 == "A172", "niewykwal_rez",
                           ifelse(credit$V17 == "A173", "wykwalifikowany", "wysokie_kwal")))

credit$V19 <-ifelse(credit$V19 == "A191", "brak", "tak")

credit$V20<-ifelse(credit$V20 == "A201", "tak", "nie")

credit$V21<-ifelse(credit$V21 == "0", "dobry", "zly")

colnames(credit) <- c("konto_czekowe", "czas", "historia", "cel", 
"kwota", "oszczednosci", "staz_pracy", "rata_%doch", "plec", "poreczyciel", 
"zamieszkanie", "zabezpieczenie", "wiek", "inne_zobow", "rodzaj_miesz", "l_kredytow", 
"kwalifikacje", "l_osob", "telefon", "obcokrajowiec", "jakosc")

credit[,names]<- lapply(credit[,names] , factor)
credit$jakosc<-as.factor(credit$jakosc)

summary(credit)
##  konto_czekowe      czas                historia         cel     
##  < 0  :274     Min.   : 4.0   brak          : 40   RTV     :280  
##  >200 : 63     1st Qu.:12.0   istniejace_spł:530   sam_nowy:234  
##  0-200:269     Median :18.0   krytyczne     :293   meble   :181  
##  brak :394     Mean   :20.9   opoznienia    : 88   sam_uzyw:103  
##                3rd Qu.:24.0   wszystkie_spł : 49   biznes  : 97  
##                Max.   :72.0                        edukacja: 50  
##                                                    (Other) : 55  
##      kwota         oszczednosci      staz_pracy    rata_%doch    plec   
##  Min.   :  250   <100    :603   <1 rok    :172   Min.   :1.000   K:310  
##  1st Qu.: 1366   >1000   : 48   >7        :253   1st Qu.:2.000   M:690  
##  Median : 2320   100-500 :103   1-4       :339   Median :3.000          
##  Mean   : 3271   500-1000: 63   4-7       :174   Mean   :2.973          
##  3rd Qu.: 3972   brak    :183   bezrobotny: 62   3rd Qu.:4.000          
##  Max.   :18424                                   Max.   :4.000          
##                                                                         
##  poreczyciel  zamieszkanie         zabezpieczenie      wiek       inne_zobow 
##  brak:907    Min.   :1.000   brak         :154    Min.   :19.00   bank :139  
##  tak : 93    1st Qu.:2.000   nieruchomosc :282    1st Qu.:27.00   brak :814  
##              Median :3.000   samochod     :332    Median :33.00   sklep: 47  
##              Mean   :2.845   ubezpieczenie:232    Mean   :35.55              
##              3rd Qu.:4.000                        3rd Qu.:42.00              
##              Max.   :4.000                        Max.   :75.00              
##                                                                              
##    rodzaj_miesz   l_kredytow              kwalifikacje     l_osob     
##  czynsz  :179   Min.   :1.000   niewykwal_nierez: 22   Min.   :1.000  
##  wlasne  :713   1st Qu.:1.000   niewykwal_rez   :200   1st Qu.:1.000  
##  za_darmo:108   Median :1.000   wykwalifikowany :630   Median :1.000  
##                 Mean   :1.407   wysokie_kwal    :148   Mean   :1.155  
##                 3rd Qu.:2.000                          3rd Qu.:1.000  
##                 Max.   :4.000                          Max.   :2.000  
##                                                                       
##  telefon    obcokrajowiec   jakosc   
##  brak:596   nie: 37       dobry:700  
##  tak :404   tak:963       zly  :300  
##                                      
##                                      
##                                      
##                                      
## 

Podsumowanie w postaci tabeli

library(sjPlot)
view_df(credit, show.frq = T, show.prc = T, show.na = T)
Data frame: credit
ID Name Label missings Values Value Labels Freq. %
1 konto_czekowe 0 (0.00%) < 0
>200
0-200
brak
274
63
269
394
27.40
6.30
26.90
39.40
2 czas 0 (0.00%) range: 4-72
3 historia 0 (0.00%) brak
istniejace_spł
krytyczne
opoznienia
wszystkie_spł
40
530
293
88
49
4.00
53.00
29.30
8.80
4.90
4 cel 0 (0.00%) AGD
biznes
edukacja
inne
meble
przekwalifikowanie
remont
RTV
sam_nowy
sam_uzyw
12
97
50
12
181
9
22
280
234
103
1.20
9.70
5.00
1.20
18.10
0.90
2.20
28.00
23.40
10.30
5 kwota 0 (0.00%) range: 250-18424
6 oszczednosci 0 (0.00%) <100
>1000
100-500
500-1000
brak
603
48
103
63
183
60.30
4.80
10.30
6.30
18.30
7 staz_pracy 0 (0.00%) <1 rok
>7
1-4
4-7
bezrobotny
172
253
339
174
62
17.20
25.30
33.90
17.40
6.20
8 rata_%doch 0 (0.00%) range: 1-4
9 plec 0 (0.00%) K
M
310
690
31.00
69.00
10 poreczyciel 0 (0.00%) brak
tak
907
93
90.70
9.30
11 zamieszkanie 0 (0.00%) range: 1-4
12 zabezpieczenie 0 (0.00%) brak
nieruchomosc
samochod
ubezpieczenie
154
282
332
232
15.40
28.20
33.20
23.20
13 wiek 0 (0.00%) range: 19-75
14 inne_zobow 0 (0.00%) bank
brak
sklep
139
814
47
13.90
81.40
4.70
15 rodzaj_miesz 0 (0.00%) czynsz
wlasne
za_darmo
179
713
108
17.90
71.30
10.80
16 l_kredytow 0 (0.00%) range: 1-4
17 kwalifikacje 0 (0.00%) niewykwal_nierez
niewykwal_rez
wykwalifikowany
wysokie_kwal
22
200
630
148
2.20
20.00
63.00
14.80
18 l_osob 0 (0.00%) range: 1-2
19 telefon 0 (0.00%) brak
tak
596
404
59.60
40.40
20 obcokrajowiec 0 (0.00%) nie
tak
37
963
3.70
96.30
21 jakosc 0 (0.00%) dobry
zly
700
300
70.00
30.00

Zapisanie obiektu

Zapisany obiekt credit zapisujemy jako zbiór danych R. Umożliwi to wczytanie bezpośrednio danych z komputera, bez konieczności każdorazowego powtarzania kodów przekształcających dane pierwotne. W ścieżce dostępu należy zamienić “" na”/“. W poniższym kodzie należy podać własną ścieżkę dostępu.

save(credit, file = "C:/Users/Dell/Documents/dysk_wymienny/zajęcia/data_mining/credit.RData")

Wczytanie danych możliwe jest za pomocą kodu:

load("C:/Users/Dell/Documents/dysk_wymienny/zajęcia/data_mining/credit.RData")

Analiza graficzna zmiennych

Zmienne dyskretne - wykres słupkowy (bar plot)

Do analizy graficznej wykorzystywany może być pakiet ggplot2 pozwalający na konstruowanie wielu rożnych typów wykresów, w zależności od charakteru zmiennych. Informacje na temat pakietu i rodzajów wykresów, które mogą zostać narysowane z wykorzystaniem pakietu można znaleźć na: https://r-charts.com/ lub https://r-graph-gallery.com/

W przypadku zmiennych dyskretnych - cech, które mogą być mierzone w skali nominalnej lub porządkowej podstawowym typem wykresu jest wykres słupkowy. Umożliwia on określenie liczby/procentu/udziału występowania danej kategorii zmiennej.

Przed narysowaniem wykresu warto zapoznać się z rozkładem danej zmiennej za pomocą fukcji table(). Funkcja ta umożliwia również konstruowanie tablic krzyżowych 2 zmiennych Podstawowy kod umożliwiający narysowanie wykresu słupkowego przy użyciu ggplot2:

library(ggplot2)
table(credit$konto_czekowe)
## 
##   < 0  >200 0-200  brak 
##   274    63   269   394
table(credit$konto_czekowe, credit$jakosc)
##        
##         dobry zly
##   < 0     139 135
##   >200     49  14
##   0-200   164 105
##   brak    348  46
ggplot(data=credit, aes(x=konto_czekowe)) +
  geom_bar()

W R możliwe jest definiowanie kolorów za pomocą ich nazw bądź symboli, zgodnie z oznaczeniami

Zmiana szerokości i koloru wypełnienia słupków

ggplot(data=credit, aes(x=konto_czekowe))+
  geom_bar(fill = "red", width=0.5)

Zmiana układu słupków z pionowego na poziome za pomocą funkcji coord_flip()

ggplot(data=credit, aes(x=konto_czekowe))+
  geom_bar(fill = "339999", width=0.5) +
  coord_flip()

Wyróżnienie różnych jakości kredytów w zależności od salda konta czekowego możliwe jest za pomocą dodania parametru fill do estetyki aes()

ggplot(data=credit, aes(x=konto_czekowe, fill = jakosc)) +
  geom_bar()

Dodanie dodatkowych elementów do wykresu umożliwia następujący kod:

ggplot(data=credit, aes(x=konto_czekowe, fill = jakosc)) +
  geom_bar() + 
  xlab("Stan konta czekowego")+
  ylab("liczba") +
  theme_minimal() +
  theme(legend.position="top", 
        axis.title = element_text(size=14, face="bold")) +
  geom_text(aes( label = ..count..), stat = "count", vjust = -0.5, colour = "black", size =4) +
  scale_x_discrete(limits=c("< 0", "0-200", ">200", "brak")) +
  scale_fill_manual(values=c("darkgreen", "brown1"))

Inny spoób prezentowania wykresu słupkowego:

  • kategorie zmiennej umieszczone obok siebie - funkcja: geom_bar(position=position_dodge()),
  • wykres udziałów poszczególnych kategorii - funkcja: geom_bar(position=position_fill()).
ggplot(data=credit, aes(x=konto_czekowe, fill = jakosc)) +
  geom_bar(position=position_dodge()) +
  scale_x_discrete(limits=c("< 0", "0-200", ">200", "brak"))

ggplot(data=credit, aes(x=konto_czekowe, fill = jakosc)) +
  geom_bar(position=position_fill()) +
  scale_x_discrete(limits=c("< 0", "0-200", ">200", "brak"))

Jedną z wad wykresu słupkowego jest brak prezentowania informacji dotyczącej liczebności poszczególnych kategorii - słupki są jednakowej szerokości niezależnie ile razy wystąpiła dana kategoria zmiennej (istnieje możliwość zmiany szerokości w ggplot za pomocą bardziej skomplikowanego kodu). Rozwiązaniem jest skonstruowanie wykresu za pomocą podstawowego pakietu do rysowania graphics.

plot(x = credit$konto_czekowe, 
     y = credit$jakosc,
     col = c( "brown1", "darkgreen"),
     xlab = "konto czekowe",
     ylab = "jakość",
     cex.axis = 1.2)

Zmienne dyskretne - wykres kołowy (bar plot)

ggplot2 nie umożliwia prostej konstrukcji wykresów kołowych. Zamiast tego pakietu można narysować wykres kołowy wykorzystując pakiet lessR

table(credit$staz_pracy)
## 
##     <1 rok         >7        1-4        4-7 bezrobotny 
##        172        253        339        174         62
library(lessR)

PieChart(staz_pracy, data = credit,
         fill = "viridis",
         main = NULL)

Zmienne ciągłe - histogram (geom_histogram)

Histogram jest wykresem zbliżonym są formą do wykresu słupkowego. Służy do przedstawiania rozkładu zmiennej ilościowej. Polega na podziale całego przedziału zmienności na mniejsze przedziały i zliczeniu ile zmiennych występuje w danych przedziałach. Kształt histogramu zależy więc od tego na ile przedziałów podzielimy zakres zmienności. Zbyt wąskie przedziały (duża liczba przedziałów) powodują, że kształt rozkładu zaciera się. Podobnie - w przypadku zbyt szerokich przedziałów (mała liczba przedziałów). Jako kryterium podziału można przyjąć, że liczba przedziałów jest równa pierwiastkowi z liczby obserwacji.

W R funkcją tworzącą histogram jest geom_histogram().

table(credit$czas)
## 
##   4   5   6   7   8   9  10  11  12  13  14  15  16  18  20  21  22  24  26  27 
##   6   1  75   5   7  49  28   9 179   4   4  64   2 113   8  30   2 184   1  13 
##  28  30  33  36  39  40  42  45  47  48  54  60  72 
##   3  40   3  83   5   1  11   5   1  48   2  13   1
ggplot(credit, aes(x= czas))+
  geom_histogram()

Kształt histogramu w zależności od liczby przedziałów:

ggplot(credit, aes(x = czas)) +
  geom_histogram(bins = 5)

ggplot(credit, aes(x = czas)) +
  geom_histogram(bins = 50)

Kształt histogramu przy przyjęciu 15 przedziałów, ze wskazaniem liczby kredytów “dobrych” i “złych” w każdym przedziale.

ggplot(credit, aes(x = czas, fill = jakosc)) +
  geom_histogram(bins = 15)

Uzupełnienie histogramu o dodatkowe informacje

ggplot(credit, aes(x = czas, fill = jakosc)) +
  geom_histogram(bins = 15, color = "white") +
  theme_minimal() +
  xlab("długość kredytów")+
  ylab("liczba") +
  theme(legend.position="top",
    plot.title = element_text(color="red", size=16, face="bold"),
    axis.text.x = element_text(color = "grey20", size = 10, angle = 0, hjust = .5, vjust = .5, face = "plain"),
    axis.text.y = element_text(color = "grey20", size = 12, angle = 0, hjust = 0.5, vjust = 1.0, face = "plain"),
    axis.title.x = element_text(color="blue", size=14, face="bold"),
    axis.title.y = element_text(color="blue", size=14, face="bold"))

Zmienne ciągłe - krzywe gęstości (geom_density)

Wykres gęstości wykorzystuje się do zaprezentowania rozkładu zmiennej ilościowej. Jest bardzo zbliżony do histogramu. Polega to na przedstawieniu bardziej płynnego rozkłady poprzez wygładzenie szumu.Główną zaletą wykresów gęstości w porównaniu z histogramami jest to, że lepiej określają kształt rozkładu, ponieważ nie wpływa na nie liczba używanych przedziałów.

W R funkcją tworzącą histogram jest geom_density().

ggplot(credit, aes(x = czas)) +
  geom_density()

Zmiana koloru linii i wypełnienia na wykresie gęstości i dołożenie krzywych pionowych wykreślonych przy wartości zmiennej równej średniej (kolor czerwony) i medianie (kolor czarny). O stylach linii można przeczytać tu.

ggplot(credit, aes(x = czas)) +
  geom_density(color="darkblue", fill="lightblue") + 
  geom_vline(aes(xintercept=mean(czas)),
    color="red", linetype="dashed", size=1) +
  geom_vline(aes(xintercept=median(czas)),
             color="black", linetype="dotdash", size=1)

Krzywe gęstości w zależności od jakości kredytu

ggplot(credit, aes(x= czas, color= jakosc))+
  geom_density()

Połączenie histogramów i krzywej gęstości

ggplot(credit, aes(x=czas, color=jakosc, fill=jakosc)) + 
  geom_histogram(aes(y=..density..), alpha=0.5, 
                 position="identity", bins = 15)+
  geom_density(alpha=.2) 

Funkcja facet_grid() umożliwia tworzenie kilku wykresów w zależności od liczby poziomów zmiennej wskazanej w nawiasie funkcji. Jeśli zmienna jakość ma dwa poziomy - “dobry” i “zły” funkcja facet_grid() utworzy dwa wykresy - w układzie pionowym lub poziomym.

ggplot(credit, aes(x=czas, color=jakosc, fill=jakosc)) + 
  geom_histogram(aes(y=..density..), alpha=0.5, 
                 position="identity", bins = 15)+
  geom_density(alpha=.2) +
  facet_grid(. ~ jakosc)

ggplot(credit, aes(x=czas, color=jakosc, fill=jakosc)) + 
  geom_histogram(aes(y=..density..), alpha=0.5, 
                 position="identity", bins = 15)+
  geom_density(alpha=.2) +
  facet_grid(jakosc ~ .)

Stworzenie histogramów prezentujących rozkład liczby kredytów w zależności od ich jakości.

ggplot(credit, aes(x = czas, fill = jakosc)) +
  geom_histogram(bins = 15, color = "white") +
  theme_minimal() +
  xlab("długość kredytów")+
  ylab("liczba") +
  theme(legend.position="top",
        plot.title = element_text(color="red", size=16, face="bold"),
        axis.text.x = element_text(color = "grey20", size = 10, angle = 0, hjust = .5, vjust = .5, face = "plain"),
        axis.text.y = element_text(color = "grey20", size = 12, angle = 0, hjust = 0.5, vjust = 1.0, face = "plain"),
        axis.title.x = element_text(color="blue", size=14, face="bold"),
        axis.title.y = element_text(color="blue", size=14, face="bold"))  +
  facet_grid(. ~ jakosc) +
  scale_fill_manual(values = c("red", "steelblue"))

Zmienne ciągłe - wykres pudełkowy (geom_boxplot)

Wykres pudełkowy jest wykresem prezentującym rozkład danej zmiennej za pomocą mediany, 1 kwartyla Q1, 3 kwartyla Q3. O sposobie interpretacji boxplotów można przeczytać na stronie

W R funkcją tworzącą wykres pudełkowy jest geom_boxplot().

table(credit$czas, credit$jakosc)
##     
##      dobry zly
##   4      6   0
##   5      1   0
##   6     66   9
##   7      5   0
##   8      6   1
##   9     35  14
##   10    25   3
##   11     9   0
##   12   130  49
##   13     4   0
##   14     3   1
##   15    52  12
##   16     1   1
##   18    71  42
##   20     7   1
##   21    21   9
##   22     2   0
##   24   128  56
##   26     1   0
##   27     8   5
##   28     2   1
##   30    27  13
##   33     2   1
##   36    46  37
##   39     4   1
##   40     0   1
##   42     8   3
##   45     1   4
##   47     1   0
##   48    20  28
##   54     1   1
##   60     7   6
##   72     0   1
ggplot(credit, aes(x = jakosc, y = czas)) +
  geom_boxplot()

Uzupełnienie wykresu pudełkowego o wartość średnią, obserwacje odstające oraz punkty - wykorzystując funkcje geom_jitter(). Rodzaje punktów, które można umieścić na wykresach przedstawione są np. tutaj

ggplot(credit, aes(x = jakosc, y = czas))+
  geom_boxplot(
    color="blue",
    fill="blue",
    alpha=0.2,
    notch=TRUE,
    notchwidth = 0.5,
    outlier.colour="red",
    outlier.fill="red",
    outlier.size=3) +
  stat_summary(fun = "mean", geom = "point", shape = 8,
               size = 2, color = "white") +
  geom_jitter(color="black", size=1.5, alpha=0.9, shape = 18)

Wykres dla dwóch zmiennych ciągłych - wykres punktowy (geom_point)

Wykres punktowy jest najprostszym sposobem przedstawienia położenia obiektów w przestrzeni dwuwymiarowej (oś X i Y).

W R funkcją tworzącą wykres punktowy jest geom_point(). W estetyce można wskazać kolor, wypełnienie i kształt punktu.

ggplot(credit, aes(x = czas, y = kwota)) +
  geom_point()

Kolor punktów, w zależności od jakości kredytów

ggplot(credit, aes(x = czas, y = kwota, color = jakosc)) +
  geom_point()

W przypadku wykresów punktowych, wykorzystując funkcje geom_smooth można przedstawić linię trendu. Metoda lm jest metodą wykreślenia lini trendu jako prostej.

ggplot(credit, aes(x = czas, y = kwota, color = jakosc)) +
  geom_point() +
  geom_smooth(se=FALSE, method = 'lm')

Prezentacja wielu zmiennych za pomocą jednego wykresu dwuwymiarowego

ggplot(credit, aes(x = czas, y = kwota, color = jakosc)) +
  geom_point() +
  geom_smooth(se=FALSE, method = 'lm') +
  facet_grid(.~ staz_pracy)

ggplot(credit, aes(x = czas, y = kwota, color = jakosc, shape = plec)) +
  geom_point() +
  geom_smooth(se=FALSE, method = 'lm') +
  facet_grid(.~ staz_pracy)

ggplot(credit, aes(x= czas, y=kwota, size = wiek, color = plec)) +
  geom_point(alpha=0.5) +
  scale_size(range = c(.1, 10), name="wiek") +
  facet_grid(. ~ jakosc)

Problem występowania wielu punktów znajdujacyh się blisko siebie w przestrzeni dwuwymiarowej można rozwiązać wykorzystując funkcję geom_hex()

ggplot(credit, aes(x=czas, y= kwota) ) +
  geom_hex(bins = 10) +
  scale_fill_continuous(type = "viridis") +
  theme_bw() +
  facet_grid(. ~ jakosc)

Wykresy dla zmiennej dyskternej i ciągłej

W przypadku wielu obserwacji przedstawienie rozkładu dwóch parametrów, z których jeden jest zmienną dyskretną i drugi - ciągłą za pomocą wykresu punktowego nie jest właściwe.

ggplot(credit, aes(x = kwalifikacje, y = kwota))+
  geom_point()

ggplot(credit, aes(x = kwalifikacje, y = kwota, color = kwalifikacje))+
  geom_point() +
 theme(legend.position = "non")

Rozwiązaniem może być “wstrząśnięcie” punktami wykorzystując do tego funkcję geom_jitter().

ggplot(credit, aes(x = kwalifikacje, y = kwota, color = kwalifikacje))+
  geom_jitter() +
  theme(legend.position = "non")

Uzupełnienie wykresu o dodatkowe statystyki - średnia (kolor czerwony) i mediana (kolor czarny).

ggplot(credit, aes(x = kwalifikacje, y = kwota, color = kwalifikacje))+
  geom_jitter() +
  theme(legend.position = "non") +
  stat_summary(geom = "point", fun = "median", color = "red", size = 5) +
  stat_summary(geom = "point", fun = "mean", color = "black", size = 4, shape = 8)

Inne sposoby prezentacji rozkładu zmiennych

library(ggridges)
ggplot(credit, aes(x = kwalifikacje, y = kwota, fill = kwalifikacje))+
  geom_violin() +
  theme(legend.position = "non")

ggplot(credit, aes(x = kwota, y = kwalifikacje, fill = kwalifikacje)) +
  geom_density_ridges(scale = 1.3,  # scale do kontrolowania nachodzenia się wykresów
                      show.legend = F)

Wykresy dla kilu zmiennych dyskretnych

R umożliwia skonstruowanie 1 wykresu prezentującego jednocześnie zależności dla kilku zmiennych ilościowych. Na rysunku tym:

  • na przekątnej przedstawiony jest rozkład każdej zmiennej,
  • poniżej przekątnej: przedstawione są dwuwymiarowe wykresy punktowe z dopasowaną linią trendu,
  • powyżej przekątnej podane są wartość współczynników korelacji Pearsona między zmiennymi wraz z poziomem istotności w postaci gwiazdek.
library("PerformanceAnalytics")
chart.Correlation(credit[,c(2,5, 8, 11, 13,16)], histogram=TRUE, method = "spearman")