Load Dataset

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.0     ✔ readr     2.1.6
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.2     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.1     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(dlookr)
## Registered S3 methods overwritten by 'dlookr':
##   method          from  
##   plot.transform  scales
##   print.transform scales
## 
## Attaching package: 'dlookr'
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
## 
## The following object is masked from 'package:base':
## 
##     transform
folderData <- "C:/Users/LUCKY SURYA/Documents/kuliah/semester 4/analisis multivariat/pertemuan 3 anmul"


data_udara <- read_delim(
  paste0(folderData, "/AirQualityUCI.csv"),
  delim = ";"
)
## Rows: 9357 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (4): CO(GT), C6H6(GT), T, AH
## dbl (8): PT08.S1(CO), NMHC(GT), PT08.S2(NMHC), NOx(GT), PT08.S3(NOx), NO2(GT...
## num (1): RH
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Mengubah koma menjadi titik

data_udara[] <- lapply(data_udara, function(x) as.numeric(gsub(",", ".", x)))
print((data_udara))
## # A tibble: 9,357 × 13
##    `CO(GT)` `PT08.S1(CO)` `NMHC(GT)` `C6H6(GT)` `PT08.S2(NMHC)` `NOx(GT)`
##       <dbl>         <dbl>      <dbl>      <dbl>           <dbl>     <dbl>
##  1      2.6          1360        150       11.9            1046       166
##  2      2            1292        112        9.4             955       103
##  3      2.2          1402         88        9               939       131
##  4      2.2          1376         80        9.2             948       172
##  5      1.6          1272         51        6.5             836       131
##  6      1.2          1197         38        4.7             750        89
##  7      1.2          1185         31        3.6             690        62
##  8      1            1136         31        3.3             672        62
##  9      0.9          1094         24        2.3             609        45
## 10      0.6          1010         19        1.7             561      -200
## # ℹ 9,347 more rows
## # ℹ 7 more variables: `PT08.S3(NOx)` <dbl>, `NO2(GT)` <dbl>,
## #   `PT08.S4(NO2)` <dbl>, `PT08.S5(O3)` <dbl>, T <dbl>, RH <dbl>, AH <dbl>
glimpse(data_udara)
## Rows: 9,357
## Columns: 13
## $ `CO(GT)`        <dbl> 2.6, 2.0, 2.2, 2.2, 1.6, 1.2, 1.2, 1.0, 0.9, 0.6, -200…
## $ `PT08.S1(CO)`   <dbl> 1360, 1292, 1402, 1376, 1272, 1197, 1185, 1136, 1094, …
## $ `NMHC(GT)`      <dbl> 150, 112, 88, 80, 51, 38, 31, 31, 24, 19, 14, 8, 16, 2…
## $ `C6H6(GT)`      <dbl> 11.9, 9.4, 9.0, 9.2, 6.5, 4.7, 3.6, 3.3, 2.3, 1.7, 1.3…
## $ `PT08.S2(NMHC)` <dbl> 1046, 955, 939, 948, 836, 750, 690, 672, 609, 561, 527…
## $ `NOx(GT)`       <dbl> 166, 103, 131, 172, 131, 89, 62, 62, 45, -200, 21, 16,…
## $ `PT08.S3(NOx)`  <dbl> 1056, 1174, 1140, 1092, 1205, 1337, 1462, 1453, 1579, …
## $ `NO2(GT)`       <dbl> 113, 92, 114, 122, 116, 96, 77, 76, 60, -200, 34, 28, …
## $ `PT08.S4(NO2)`  <dbl> 1692, 1559, 1555, 1584, 1490, 1393, 1333, 1333, 1276, …
## $ `PT08.S5(O3)`   <dbl> 1268, 972, 1074, 1203, 1110, 949, 733, 730, 620, 501, …
## $ T               <dbl> 13.6, 13.3, 11.9, 11.0, 11.2, 11.2, 11.3, 10.7, 10.7, …
## $ RH              <dbl> 489, 477, 54, 60, 596, 592, 568, 60, 597, 602, 605, 56…
## $ AH              <dbl> 0.7578, 0.7255, 0.7502, 0.7867, 0.7888, 0.7848, 0.7603…

karena bahasa r menerima data float menggunakan titik

sum(is.na(data_udara))
## [1] 0

Boxplot (deteksi outlier)

data_udara %>%
  pivot_longer(cols = everything(),
               names_to = "Variabel",
               values_to = "Nilai") %>%
  ggplot(aes(x = Variabel, y = Nilai)) +
  geom_boxplot(fill = "orange") +
  coord_flip() +
  theme_minimal() +
  labs(title = "Boxplot Setiap Variabel",
       x = NULL,
       y = "Nilai")

berdasarkan hasil plot terdapat banyak outlier yang tersebar pada setiap fitur

Interpolasi

data_udara[data_udara == -200] <- NA

library(zoo)
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
data_udara <- data_udara %>%
  mutate(across(where(is.numeric), ~ na.approx(., na.rm = FALSE))) %>%
  mutate(across(where(is.numeric), ~ na.locf(., na.rm = FALSE))) %>%
  mutate(across(where(is.numeric), ~ na.locf(., fromLast = TRUE)))

pada dataset air quality sebagai data time series nilai dari -200 dianggap sebagai missing value sehingga cara penangannya yaitu di interpolasikan. JIka langsung di drop satu baris hal itu akan sangat mengurangi data yang berpengaruh ke dalam model.

Statistika Deskriptif

stat_deskriptif <- data.frame(
  Variabel = colnames(data_udara),
  Minimum = apply(data_udara, 2, min, na.rm = TRUE),
  Maksimum = apply(data_udara, 2, max, na.rm = TRUE),
  Mean = round(apply(data_udara, 2, mean, na.rm = TRUE), 3),
  Std_Dev = round(apply(data_udara, 2, sd, na.rm = TRUE), 3)
)

knitr::kable(
  stat_deskriptif,
  #caption = "Tabel 1. Statistika Deskriptif Variabel Penelitian"
)
Variabel Minimum Maksimum Mean Std_Dev
CO(GT) CO(GT) 0.1000 11.900 2.131 1.432
PT08.S1(CO) PT08.S1(CO) 647.0000 2040.000 1103.060 218.196
NMHC(GT) NMHC(GT) 7.0000 1189.000 269.834 74.252
C6H6(GT) C6H6(GT) 0.1000 63.700 10.179 7.504
PT08.S2(NMHC) PT08.S2(NMHC) 383.0000 2214.000 942.143 267.867
NOx(GT) NOx(GT) 2.0000 1479.000 241.922 204.315
PT08.S3(NOx) PT08.S3(NOx) 322.0000 2683.000 832.759 255.710
NO2(GT) NO2(GT) 2.0000 340.000 109.632 46.462
PT08.S4(NO2) PT08.S4(NO2) 551.0000 2775.000 1453.299 343.206
PT08.S5(O3) PT08.S5(O3) 221.0000 2523.000 1032.544 404.448
T T -1.9000 44.600 18.233 8.782
RH RH 10.0000 887.000 445.885 209.655
AH AH 0.1847 2.231 1.020 0.402
corr <-cor(data_udara)
corr
##                    CO(GT) PT08.S1(CO)    NMHC(GT)    C6H6(GT) PT08.S2(NMHC)
## CO(GT)         1.00000000  0.79405446  0.26750239  0.81651815    0.80709429
## PT08.S1(CO)    0.79405446  1.00000000  0.23450242  0.88050678    0.89204527
## NMHC(GT)       0.26750239  0.23450242  1.00000000  0.23338212    0.23382543
## C6H6(GT)       0.81651815  0.88050678  0.23338212  1.00000000    0.98227741
## PT08.S2(NMHC)  0.80709429  0.89204527  0.23382543  0.98227741    1.00000000
## NOx(GT)        0.79127203  0.66709860  0.14174699  0.65500884    0.64692509
## PT08.S3(NOx)  -0.64771255 -0.77708257 -0.25888994 -0.73100040   -0.79318030
## NO2(GT)        0.67580351  0.61771356  0.18671130  0.57026898    0.60164989
## PT08.S4(NO2)   0.55656356  0.66736052  0.17317355  0.75226916    0.76528987
## PT08.S5(O3)    0.77481719  0.90173053  0.20310747  0.85848251    0.87513007
## T              0.01889891  0.03123799  0.07944770  0.19059773    0.23056903
## RH             0.04092761  0.07299005 -0.03701566 -0.05778683   -0.07591059
## AH             0.06026414  0.11224074  0.06037334  0.15176418    0.17034403
##                  NOx(GT) PT08.S3(NOx)     NO2(GT) PT08.S4(NO2) PT08.S5(O3)
## CO(GT)         0.7912720  -0.64771255  0.67580351    0.5565636  0.77481719
## PT08.S1(CO)    0.6670986  -0.77708257  0.61771356    0.6673605  0.90173053
## NMHC(GT)       0.1417470  -0.25888994  0.18671130    0.1731736  0.20310747
## C6H6(GT)       0.6550088  -0.73100040  0.57026898    0.7522692  0.85848251
## PT08.S2(NMHC)  0.6469251  -0.79318030  0.60164989    0.7652899  0.87513007
## NOx(GT)        1.0000000  -0.62681354  0.76303802    0.2146550  0.73598198
## PT08.S3(NOx)  -0.6268135   1.00000000 -0.62214221   -0.5286039 -0.79837530
## NO2(GT)        0.7630380  -0.62214221  1.00000000    0.1342030  0.67975367
## PT08.S4(NO2)   0.2146550  -0.52860393  0.13420299    1.0000000  0.56954459
## PT08.S5(O3)    0.7359820  -0.79837530  0.67975367    0.5695446  1.00000000
## T             -0.2462799  -0.12659189 -0.19441838    0.5608469 -0.04750581
## RH             0.1437271  -0.04271305 -0.07058327   -0.0169087  0.08586366
## AH            -0.1226303  -0.21247527 -0.32224271    0.6294811  0.04461077
##                         T          RH          AH
## CO(GT)         0.01889891  0.04092761  0.06026414
## PT08.S1(CO)    0.03123799  0.07299005  0.11224074
## NMHC(GT)       0.07944770 -0.03701566  0.06037334
## C6H6(GT)       0.19059773 -0.05778683  0.15176418
## PT08.S2(NMHC)  0.23056903 -0.07591059  0.17034403
## NOx(GT)       -0.24627989  0.14372709 -0.12263028
## PT08.S3(NOx)  -0.12659189 -0.04271305 -0.21247527
## NO2(GT)       -0.19441838 -0.07058327 -0.32224271
## PT08.S4(NO2)   0.56084692 -0.01690870  0.62948113
## PT08.S5(O3)   -0.04750581  0.08586366  0.04461077
## T              1.00000000 -0.41659281  0.65876052
## RH            -0.41659281  1.00000000  0.13809711
## AH             0.65876052  0.13809711  1.00000000
library(corrr)
## 
## Attaching package: 'corrr'
## The following object is masked from 'package:dlookr':
## 
##     correlate
library(ggcorrplot)

ggcorrplot(corr, lab = TRUE, lab_size = 3, type = "full")
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## ℹ The deprecated feature was likely used in the ggcorrplot package.
##   Please report the issue at <https://github.com/kassambara/ggcorrplot/issues>.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

##Cek MSA menggunakan Uji KMO dan Barlets

library(psych)
## 
## Attaching package: 'psych'
## The following object is masked from 'package:dlookr':
## 
##     describe
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
corr<- cor(data_udara)
KMO(corr)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = corr)
## Overall MSA =  0.82
## MSA for each item = 
##        CO(GT)   PT08.S1(CO)      NMHC(GT)      C6H6(GT) PT08.S2(NMHC) 
##          0.91          0.94          0.81          0.84          0.79 
##       NOx(GT)  PT08.S3(NOx)       NO2(GT)  PT08.S4(NO2)   PT08.S5(O3) 
##          0.81          0.82          0.89          0.75          0.95 
##             T            RH            AH 
##          0.58          0.36          0.44
data_udara =  data_udara[ ,-12]
corr<- cor(data_udara)
KMO(corr)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = corr)
## Overall MSA =  0.82
## MSA for each item = 
##        CO(GT)   PT08.S1(CO)      NMHC(GT)      C6H6(GT) PT08.S2(NMHC) 
##          0.91          0.94          0.80          0.84          0.78 
##       NOx(GT)  PT08.S3(NOx)       NO2(GT)  PT08.S4(NO2)   PT08.S5(O3) 
##          0.79          0.81          0.88          0.74          0.94 
##             T            AH 
##          0.62          0.43
data_udara =  data_udara[ ,-12]
corr<- cor(data_udara)
KMO(corr)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = corr)
## Overall MSA =  0.86
## MSA for each item = 
##        CO(GT)   PT08.S1(CO)      NMHC(GT)      C6H6(GT) PT08.S2(NMHC) 
##          0.89          0.93          0.78          0.82          0.81 
##       NOx(GT)  PT08.S3(NOx)       NO2(GT)  PT08.S4(NO2)   PT08.S5(O3) 
##          0.87          0.88          0.86          0.79          0.94 
##             T 
##          0.51
KMO_result<-KMO(corr)

kmo_table <- data.frame(
  Variabel = names(KMO_result$MSAi),
  MSA = round(KMO_result$MSAi,3)
)
kmo_table
##                    Variabel   MSA
## CO(GT)               CO(GT) 0.894
## PT08.S1(CO)     PT08.S1(CO) 0.933
## NMHC(GT)           NMHC(GT) 0.781
## C6H6(GT)           C6H6(GT) 0.822
## PT08.S2(NMHC) PT08.S2(NMHC) 0.814
## NOx(GT)             NOx(GT) 0.866
## PT08.S3(NOx)   PT08.S3(NOx) 0.880
## NO2(GT)             NO2(GT) 0.865
## PT08.S4(NO2)   PT08.S4(NO2) 0.794
## PT08.S5(O3)     PT08.S5(O3) 0.938
## T                         T 0.507
#Bartlett Test
library(psych)
uji_barlets<-cortest.bartlett(corr, n = nrow(data_udara))
print(uji_barlets)
## $chisq
## [1] 133895.9
## 
## $p.value
## [1] 0
## 
## $df
## [1] 55

Scaling (standardisasi data)

scale_data = scale(data_udara)
r = cov(scale_data)
r
##                    CO(GT) PT08.S1(CO)   NMHC(GT)   C6H6(GT) PT08.S2(NMHC)
## CO(GT)         1.00000000  0.79405446  0.2675024  0.8165181     0.8070943
## PT08.S1(CO)    0.79405446  1.00000000  0.2345024  0.8805068     0.8920453
## NMHC(GT)       0.26750239  0.23450242  1.0000000  0.2333821     0.2338254
## C6H6(GT)       0.81651815  0.88050678  0.2333821  1.0000000     0.9822774
## PT08.S2(NMHC)  0.80709429  0.89204527  0.2338254  0.9822774     1.0000000
## NOx(GT)        0.79127203  0.66709860  0.1417470  0.6550088     0.6469251
## PT08.S3(NOx)  -0.64771255 -0.77708257 -0.2588899 -0.7310004    -0.7931803
## NO2(GT)        0.67580351  0.61771356  0.1867113  0.5702690     0.6016499
## PT08.S4(NO2)   0.55656356  0.66736052  0.1731736  0.7522692     0.7652899
## PT08.S5(O3)    0.77481719  0.90173053  0.2031075  0.8584825     0.8751301
## T              0.01889891  0.03123799  0.0794477  0.1905977     0.2305690
##                  NOx(GT) PT08.S3(NOx)    NO2(GT) PT08.S4(NO2) PT08.S5(O3)
## CO(GT)         0.7912720   -0.6477126  0.6758035    0.5565636  0.77481719
## PT08.S1(CO)    0.6670986   -0.7770826  0.6177136    0.6673605  0.90173053
## NMHC(GT)       0.1417470   -0.2588899  0.1867113    0.1731736  0.20310747
## C6H6(GT)       0.6550088   -0.7310004  0.5702690    0.7522692  0.85848251
## PT08.S2(NMHC)  0.6469251   -0.7931803  0.6016499    0.7652899  0.87513007
## NOx(GT)        1.0000000   -0.6268135  0.7630380    0.2146550  0.73598198
## PT08.S3(NOx)  -0.6268135    1.0000000 -0.6221422   -0.5286039 -0.79837530
## NO2(GT)        0.7630380   -0.6221422  1.0000000    0.1342030  0.67975367
## PT08.S4(NO2)   0.2146550   -0.5286039  0.1342030    1.0000000  0.56954459
## PT08.S5(O3)    0.7359820   -0.7983753  0.6797537    0.5695446  1.00000000
## T             -0.2462799   -0.1265919 -0.1944184    0.5608469 -0.04750581
##                         T
## CO(GT)         0.01889891
## PT08.S1(CO)    0.03123799
## NMHC(GT)       0.07944770
## C6H6(GT)       0.19059773
## PT08.S2(NMHC)  0.23056903
## NOx(GT)       -0.24627989
## PT08.S3(NOx)  -0.12659189
## NO2(GT)       -0.19441838
## PT08.S4(NO2)   0.56084692
## PT08.S5(O3)   -0.04750581
## T              1.00000000
library(corrr)
library(ggcorrplot)

ggcorrplot(r, lab = TRUE, lab_size = 3, type = "full")

PCA

library('FactoMineR')
library('factoextra')
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
pca_result <- PCA(data_udara,
                  scale.unit = TRUE,
                  graph = FALSE,
                  ncp=ncol(data_udara))     


pca_result$eig          
##         eigenvalue percentage of variance cumulative percentage of variance
## comp 1  6.75985600            61.45323633                          61.45324
## comp 2  1.75131088            15.92100798                          77.37424
## comp 3  0.93525473             8.50231571                          85.87656
## comp 4  0.48703526             4.42759326                          90.30415
## comp 5  0.39875966             3.62508780                          93.92924
## comp 6  0.22605614             2.05505582                          95.98430
## comp 7  0.14775058             1.34318706                          97.32748
## comp 8  0.11656466             1.05967874                          98.38716
## comp 9  0.08534334             0.77584852                          99.16301
## comp 10 0.08170581             0.74278009                          99.90579
## comp 11 0.01036296             0.09420869                         100.00000
#pca_result$svd$V        
#pca_result$ind['coord']
#pca_result$var
pca_table <- data.frame(
  Komponen = paste0("PC", 1:nrow(pca_result$eig)),
  Eigenvalue = pca_result$eig[,1],
  Variance_Percent = pca_result$eig[,2],
  Cumulative_Variance = pca_result$eig[,3]
)

knitr::kable(pca_table, digits = 3)
Komponen Eigenvalue Variance_Percent Cumulative_Variance
comp 1 PC1 6.760 61.453 61.453
comp 2 PC2 1.751 15.921 77.374
comp 3 PC3 0.935 8.502 85.877
comp 4 PC4 0.487 4.428 90.304
comp 5 PC5 0.399 3.625 93.929
comp 6 PC6 0.226 2.055 95.984
comp 7 PC7 0.148 1.343 97.327
comp 8 PC8 0.117 1.060 98.387
comp 9 PC9 0.085 0.776 99.163
comp 10 PC10 0.082 0.743 99.906
comp 11 PC11 0.010 0.094 100.000
loading <- pca_result$var$coord[,1:2]

colnames(loading) <- c("PC1", "PC2")

knitr::kable(round(loading,3))
PC1 PC2
CO(GT) 0.890 -0.104
PT08.S1(CO) 0.935 0.012
NMHC(GT) 0.292 0.085
C6H6(GT) 0.944 0.161
PT08.S2(NMHC) 0.959 0.180
NOx(GT) 0.781 -0.470
PT08.S3(NOx) -0.848 -0.010
NO2(GT) 0.725 -0.475
PT08.S4(NO2) 0.680 0.661
PT08.S5(O3) 0.932 -0.110
T 0.101 0.882
# membuat scree plot
eigenvalues <- pca_result$eig[,1]

plot(eigenvalues,
     type="b",
     xlab="Komponen",
     ylab="Eigenvalue",
     main="Scree Plot")
abline(h=1, col="red")

#Biplot
fviz_pca_biplot(pca_result,
                geom.ind = "point",
                #col.ind = status.ipm,
                #palette = c("#FC4E07","#E7B800", "#00AFBB"),
                addEllipses = TRUE,
                #legend.title = "Kategori"
                )
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## ℹ The deprecated feature was likely used in the ggpubr package.
##   Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

# correlation circle
contrib_circle <- fviz_pca_var(pca_result, col.var = "contrib",
                               gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"),
                               repel = TRUE) +
  ggtitle("Kontribusi Variabel")
plot(contrib_circle)

#contribution
contrib_v_PC1 <- fviz_contrib(pca_result, choice = "var", axes = 1, top = 5) + ggtitle("PC1")
plot(contrib_v_PC1)

contrib_v_PC2 <- fviz_contrib(pca_result, choice = "var", axes = 2, top = 5) + ggtitle("PC2")
plot(contrib_v_PC2)

Faktor Analisis

fa.parallel(scale_data)

## Parallel analysis suggests that the number of factors =  4  and the number of components =  2
FA <- fa(scale_data,
         covar = TRUE,
         nfactors = 2,
         rotate = "varimax", fm="pm")
## factor method not specified correctly, minimum residual (unweighted least squares  used
load <- FA$loadings
load
## 
## Loadings:
##               MR1    MR2   
## CO(GT)         0.869  0.119
## PT08.S1(CO)    0.894  0.250
## NMHC(GT)       0.237  0.100
## C6H6(GT)       0.871  0.399
## PT08.S2(NMHC)  0.886  0.426
## NOx(GT)        0.864 -0.255
## PT08.S3(NOx)  -0.791 -0.202
## NO2(GT)        0.792 -0.251
## PT08.S4(NO2)   0.480  0.865
## PT08.S5(O3)    0.924  0.128
## T                     0.677
## 
##                  MR1   MR2
## SS loadings    6.245 1.819
## Proportion Var 0.568 0.165
## Cumulative Var 0.568 0.733
load_table <- as.data.frame(unclass(FA$loadings))

load_table$Variabel <- rownames(load_table)

colnames(load_table)[1:2] <- c("Faktor Polutan", "Faktor Lingkungan")

load_table <- load_table[, c("Faktor Polutan", 
                             "Faktor Lingkungan")]

load_table <- load_table[order(-abs(load_table$`Faktor Polutan`)), ]

knitr::kable(load_table, digits = 3, caption = "Tabel Factor Loadings")
Tabel Factor Loadings
Faktor Polutan Faktor Lingkungan
PT08.S5(O3) 0.924 0.128
PT08.S1(CO) 0.894 0.250
PT08.S2(NMHC) 0.886 0.426
C6H6(GT) 0.871 0.399
CO(GT) 0.869 0.119
NOx(GT) 0.864 -0.255
NO2(GT) 0.792 -0.251
PT08.S3(NOx) -0.791 -0.202
PT08.S4(NO2) 0.480 0.865
NMHC(GT) 0.237 0.100
T -0.084 0.677
#FA$scores
colnames(FA$loadings) <- c("faktor Polusi", "Faktor lingkungan")

fa.diagram(FA)