Bài viết này giới thiệu cho các bạn hàm sử dụng để tính BẢNG Các chỉ số về độ tin cậy tổng hợp, giá trị hội tụ và giá trị phân biệt của các biến của model CFA.
Chúng ta sẽ sử dụng 1 hàm tự code, tên là funCFA(), dựa trên hàm của gói lệnh semTools, require(semTools).
Hàm funCFA() được sử dụng nhiều lần mỗi khi chúng ta cần tính các chỉ số trên
Tài liệu phục vụ HỘI THẢO THỐNG KÊ TRONG KHOA HỌC XÃ HỘI VỚI PHẦN MỀM MÃ NGUỒN MỞ R Chi tiết tại: https://sites.google.com/view/tkud https://viasm.edu.vn/
Dữ liệu sử dụng trong hướng dẫn này là của PGS.TS Trần Văn Trang (Đại học Thương mại).
Bài báo gốc lấy tại: http://tckhtm.tmu.edu.vn/vi/news/cac-so-tap-chi/tap-chi-khoa-hoc-thuong-mai-so-141-153.html
Dữ liệu tải tại google diver: https://drive.google.com/drive/folders/1Npip6h8WyZjI9JGf5wonnU_scBUYj4sP?usp=sharing
setwd("D:/Tap huan VIASM/HoiThao_KHXH_2021/Projects/Y_Dinh_Hanh_Vi")
library(foreign)
require(tidyverse)
require(lavaan)
require(semTools)
d <- read.spss("Case study Behavior Intention.sav",
use.value.label=TRUE, to.data.frame=TRUE)
d1 <- d %>% select(-c("STT", "FAM", "Formation",
"Work", "Year",
"BI1", "BIRecode", "BI4"))
Đây là hàm tự viết code, không thuộc gói lệnh nào và được định nghĩa như dưới này.
Sử dụng: Hàm có hai tham số đầu vào là:
modelCFA: Là kết quả ước lượng sau khi dùng hàm cfa() trong lavaan
ndigit: số lượng chữ số thập phân
Định nghĩa hàm như dưới này
#----------------By Huong Trinh (TMU), 27_8_2021
# For: https://viasm.edu.vn/hdkh/hoi-thao-thong-ke-trong-khoa-hoc-xa-hoi-voi-phan-mem-ma-nguon-mo-r
funCFA <- function(modelCFA, ndigit )
{
# modelCFA: A CFA mode, after using cfa function in Lavaan
# ndigit: number of digits
#Find auto latents
Varlatent <- standardizedSolution(modelCFA) %>%
filter(op == "=~") %>%
select(lhs) %>%
unique()
nVl <- length(Varlatent$lhs)
# Find items
VarItems <- list()
for ( i in Varlatent$lhs)
{
VarItems[[i]] <- standardizedSolution(modelCFA) %>%
filter(op == "=~" & lhs == i) %>% select(rhs) %>% unique()
}
# Prepare table form
TabMDF <- data.frame(Latent = Varlatent$lhs,
CR = rep(NA, nVl),
AVE = rep(NA, nVl), MSV = rep(NA, nVl))
for ( i in Varlatent$lhs)
{
TabMDF[, i] <- NA
}
#-----------------Fill cot CR
sl <- standardizedSolution(modelCFA)
sl <- sl$est.std[sl$op == "=~"] # estimated deviation
names(sl) <- modelCFA@Model@ dimNames[[2]][[1]] # to take item's names of used model
#Compute residual variance of each item
re <- 1 - sl^2
#CR for each latent
for ( i in 1: length(Varlatent$lhs))
{
nlt <- Varlatent$lhs[i]
vitems <- VarItems[[i]]$rhs
TabMDF[TabMDF$Latent == nlt, "CR"] <- round(sum(sl[ vitems ])^2/(sum(sl[ vitems])^2 + sum(re[ vitems])), ndigit)
}
#=======reliability and validity===============================================
#Calculate reliability values of factors
#AVE
AVE <- semTools::reliability (modelCFA)
AVE <- round(AVE["avevar", ], ndigit)
for ( i in 1: length(Varlatent$lhs))
{
nlt <- Varlatent$lhs[i]
TabMDF[TabMDF$Latent == nlt, "AVE"] <- AVE[ nlt ]
}
#MSV
MSV4a <- semTools::discriminantValidity (modelCFA) # He so tuong quan giua cac bien
for ( i in 1: length(Varlatent$lhs))
{
nlt <- Varlatent$lhs[i]
tempMSV <- MSV4a %>% filter(lhs == nlt |rhs== nlt ) %>%
select(est) %>% max()
TabMDF[TabMDF$Latent == nlt, "MSV"] <- round(tempMSV^2, ndigit)
}
#MACOR
MACOR <- MSV4a %>% select(c(lhs, op, rhs , est, 'Pr(>Chisq)'))
pvalue <- ifelse(MACOR$'Pr(>Chisq)' <= 0.001, "***",
ifelse(MACOR$'Pr(>Chisq)' > 0.001 &MACOR$ 'Pr(>Chisq)'<0.01, "**",
ifelse(MACOR$'Pr(>Chisq)' > 0.01 & MACOR$'Pr(>Chisq)'<0.05, "*", " ")))
MACOR <- MACOR %>% mutate(estF = paste0(round(MACOR$est, ndigit), pvalue)) %>%
select(lhs, op, rhs, estF)
#MACOR
for ( i in 1: length(Varlatent$lhs))
{
nlti <- Varlatent$lhs[i]
for ( j in 1: length(Varlatent$lhs))
{
nltj <- Varlatent$lhs[j]
MACORtempts <- MACOR[ MACOR$lhs == nlti & MACOR$rhs == nltj, "estF"]
TabMDF[TabMDF$Latent == nltj, nlti] <-
ifelse(i == j , round( sqrt(TabMDF[TabMDF$Latent == nlti, "AVE"]), ndigit ), MACORtempts)
}
}
return(TabMDF)
}
cfa.model2 <- ' BEINTEN =~ BI2 + BI3 + BI5 + BI6
RELA =~ REL1 + REL2 + REL3+ REL4
EDUC =~ EDU1 + EDU2 + EDU3 + EDU4 + EDU5 + EDU6 + EDU7 + EDU8
GOVE =~ GOV1 + GOV2 + GOV3 + GOV4 + GOV5
ENDO =~ END1 + END2 + END3 + END4 + END5 ' #No END1 in the Trang (2020)
cfa.d2 <- cfa(cfa.model2, data = d1)
#=======reliability and validity by funCFA ===============================================
Table.cfa.d2 <- funCFA(cfa.d2, ndigit = 2)
## Some of the latent variable variances are estimated instead of fixed to 1. The model is re-estimated by scaling the latent variables by fixing their variances and freeing all factor loadings.
Table.cfa.d2
## Latent CR AVE MSV BEINTEN RELA EDUC GOVE ENDO
## 1 BEINTEN 0.80 0.50 0.44 0.71 <NA> <NA> <NA> <NA>
## 2 RELA 0.82 0.55 0.44 0.67*** 0.74 <NA> <NA> <NA>
## 3 EDUC 0.91 0.57 0.32 0.38*** 0.47*** 0.75 <NA> <NA>
## 4 GOVE 0.87 0.56 0.32 0.37*** 0.41*** 0.57*** 0.75 <NA>
## 5 ENDO 0.84 0.51 0.08 -0.03*** 0.02*** 0.28*** 0.26*** 0.71
write.csv(Table.cfa.d2, file = "Table.cfa.d2.csv")
cfa.model4a <- ' BEINTEN =~ BI2 + BI3 + BI5 + BI6
RELA =~ REL1 + REL2 + REL3+ REL4
EDUC =~ EDU1 + EDU2 + EDU3 + EDU4 + EDU5 + EDU6 + EDU7 + EDU8
GOVE =~ GOV1 + GOV2 + GOV3 + GOV4 + GOV5
ENDO =~ END2 + END3 + END4 + END5
# Covariance
BI2 ~~ BI3
REL4 ~~ REL1 + REL3
EDU2 ~~ EDU1 + EDU3 + EDU6
EDU5 ~~ EDU6
EDU7 ~~ EDU8
GOV4 ~~ GOV5
END5 ~~ END4 '
cfa.d4a <- cfa(cfa.model4a, data = d1)
#=======reliability and validity by funCFA ===============================================
Table.cfa.d4a <- funCFA(cfa.d4a, ndigit = 2)
## Some of the latent variable variances are estimated instead of fixed to 1. The model is re-estimated by scaling the latent variables by fixing their variances and freeing all factor loadings.
## Warning in lav_object_post_check(object): lavaan WARNING: covariance matrix of latent variables
## is not positive definite;
## use lavInspect(fit, "cov.lv") to investigate.
Table.cfa.d4a
## Latent CR AVE MSV BEINTEN RELA EDUC GOVE ENDO
## 1 BEINTEN 0.78 0.48 0.47 0.69 <NA> <NA> <NA> <NA>
## 2 RELA 0.82 0.55 0.47 0.69*** 0.74 <NA> <NA> <NA>
## 3 EDUC 0.91 0.55 0.34 0.4*** 0.44*** 0.74 <NA> <NA>
## 4 GOVE 0.86 0.55 0.34 0.36*** 0.39*** 0.58*** 0.74 <NA>
## 5 ENDO 0.82 0.52 0.06 -0.05*** -0.03*** 0.24*** 0.23*** 0.72
write.csv(Table.cfa.d4a, file = "Table.cfa.d4a.csv")
Trân trọng cảm ơn!