Poder Calorífico Superior em função da Composição Química da biomassa
Instalação do pacote e verificação se todos estão instalados. O Comando abaixo ajuda a verificar se os pacotes estão instalados, ou se necessitam ser instalados.
pacotes <- c("tidyverse", "readxl", "ggpubr", "kableExtra",
"PerformanceAnalytics", "scatterplot3d", "MASS",
"gridExtra", "car", "lmtest", "plyr", "knitr", "dplyr")
if(sum(as.numeric(!pacotes %in% installed.packages())) != 0){
instalador <- pacotes[!pacotes %in% installed.packages()]
for(i in 1:length(instalador)) {
install.packages(instalador, dependencies = T)
break()}
sapply(pacotes, require, character = T)
} else {
sapply(pacotes, require, character = T)
}## tidyverse readxl ggpubr
## TRUE TRUE TRUE
## kableExtra PerformanceAnalytics scatterplot3d
## TRUE TRUE TRUE
## MASS gridExtra car
## TRUE TRUE TRUE
## lmtest plyr knitr
## TRUE TRUE TRUE
## dplyr
## TRUE
O Poder calorífico é uma medida da quantidade de energia térmica liberada, na forma de calor, na queima completa de 1kg de combustível. O objetivo principal dessa modelagem é verificar se o Poder Calorífico (PC) tem correlação com a Composição Química da biomassa (teor de lignina, polissacarídeos e extrativos). Caso haja associação entre essas variáveis, interpretar a modelagem estatística realizada e a influência de cada variável no valor do PC, por meio da comparação da magnitude dos betas da equação de regressão ajustada. Adicionalmente, avaliar a qualidade dos dados experimentais por meio das seguintes estatísticas descritivas: média, desvio padrão, coeficiente de variação e score z. Como referência para a Área de Tecnologia da Madeira, nas disciplinas ministradas pela professora Gilmara, deve-se considerar dados de excelente qualidade se o Coeficiente de variação tiver valor de até 10%, de 10 a 20% dados bons, de 20 a 30 % dados ruins e acima de 30% dados péssimos. Também, no que se refere ao score Z, valores em módulo acima de 2 serão considerados como outliers (pontos atípicos). Os outliers também serão identificados por meio de gráficos box plot das variáveis do modelo.
tabela3 <- read_excel("Dados.xlsx",
sheet = "Composicao_quimica")tabela3 %>%
kbl(caption = "Tabela dos Dados", align = 'cc') %>%
kable_classic(full_width = F, html_font = "Times", font_size = 12)| extrativos | lignina | holocelulose | PCS |
|---|---|---|---|
| 2.9434407 | 29.86403 | 67.19253 | 17.52720 |
| 2.7417815 | 29.96502 | 67.29320 | 17.64854 |
| 2.6133189 | 30.74463 | 66.64205 | 17.67364 |
| 1.0326479 | 30.52474 | 68.44261 | 17.48536 |
| 1.2695355 | 29.73810 | 68.99236 | 17.49372 |
| 0.8540925 | 29.79510 | 69.35080 | 17.58996 |
| 1.2518575 | 29.12709 | 69.62106 | 17.62762 |
| 1.3169764 | 29.30707 | 69.37595 | 17.78661 |
| 1.0532025 | 28.41579 | 70.53101 | 17.59414 |
| 1.6052158 | 29.68110 | 68.71369 | 17.07531 |
| 1.7641220 | 30.03399 | 68.20188 | 17.32218 |
| 1.8730302 | 29.15542 | 68.97155 | 17.25105 |
| 2.5166644 | 27.63171 | 69.85163 | 17.34310 |
| 1.9856993 | 27.77445 | 70.23986 | 17.29707 |
| 1.9593548 | 28.24153 | 69.79912 | 17.36820 |
| 1.8144348 | 29.25707 | 68.92849 | 17.43933 |
| 1.9256605 | 29.18541 | 68.88893 | 17.38494 |
| 1.2597507 | 30.25092 | 68.48932 | 17.42678 |
| 1.8393206 | 28.46292 | 69.69776 | 17.31381 |
| 1.9124465 | 28.74425 | 69.34330 | 17.46025 |
| 1.9287968 | 28.08158 | 69.98963 | 17.54812 |
| 2.7028249 | 29.19124 | 68.10593 | 17.80335 |
| 3.7316788 | 31.36373 | 64.90459 | 17.76569 |
| 3.3813145 | 30.27092 | 66.34777 | 17.74059 |
| 1.9874762 | 30.61163 | 67.40089 | 17.48954 |
| 2.1662125 | 31.01380 | 66.81999 | 17.41423 |
| 2.3980380 | 30.81384 | 66.78812 | 17.58577 |
# Poder Calorífico Superior
y <- tabela3$PCS
mean_and_sd <- function(y) {
m <- mean(y) # média
s <- sd(y) # desvio padrão
# sprintf("%0.3f U00B1 %0.3f", m, s)
sprintf("%0.2f $\\pm$ %0.2f", m, s)}
Med_e_sd<- mean_and_sd(y)
cv <- function(y) {100 * sd(y)/mean(y)}
Coef_de_Variacao<-cv(y) # coeficiente de variação
Coef_de_Variacao<-round(Coef_de_Variacao, 2)
PCS<-data.frame(Med_e_sd, Coef_de_Variacao)
# Extrativos
y <- tabela3$extrativos
mean_and_sd <- function(y) {
m <- mean(y) # média
s <- sd(y) # desvio padrão
# sprintf("%0.3f U00B1 %0.3f", m, s)
sprintf("%0.2f $\\pm$ %0.2f", m, s)}
Med_e_sd<- mean_and_sd(y)
cv <- function(y) {100 * sd(y)/mean(y)}
Coef_de_Variacao<-cv(y) # coeficiente de variação
Coef_de_Variacao<-round(Coef_de_Variacao, 2)
extrativos<-data.frame(Med_e_sd, Coef_de_Variacao)
# Lignina
y <- tabela3$lignina
mean_and_sd <- function(y) {
m <- mean(y) # média
s <- sd(y) # desvio padrão
# sprintf("%0.3f U00B1 %0.3f", m, s)
sprintf("%0.2f $\\pm$ %0.2f", m, s)}
Med_e_sd<- mean_and_sd(y)
cv <- function(y) {100 * sd(y)/mean(y)}
Coef_de_Variacao<-cv(y) # coeficiente de variação
Coef_de_Variacao<-round(Coef_de_Variacao, 2)
lignina<-data.frame(Med_e_sd, Coef_de_Variacao)
# Holocelulose
y <- tabela3$holocelulose
mean_and_sd <- function(y) {
m <- mean(y) # média
s <- sd(y) # desvio padrão
# sprintf("%0.3f U00B1 %0.3f", m, s)
sprintf("%0.2f $\\pm$ %0.2f", m, s)}
Med_e_sd<- mean_and_sd(y)
cv <- function(y) {100 * sd(y)/mean(y)}
Coef_de_Variacao<-cv(y) # coeficiente de variação
Coef_de_Variacao<-round(Coef_de_Variacao, 2)
holocelulose<-data.frame(Med_e_sd, Coef_de_Variacao)
# Junção dos data.frame
dados<-rbind(PCS,extrativos)
dados<-rbind(dados, lignina)
dados<-rbind(dados, holocelulose)
# Criar uma coluna com o nome das variáveis
dados<-mutate(dados,
Variaveis=c("Poder Calorífico Superior (MJ/kg)",
"Extrativos", "Lignina", "Holocelulose"))
dados<-data.frame(dados)
#Organizar as colunas no data.frame
date<-dplyr::select(dados, Variaveis, Med_e_sd, Coef_de_Variacao)
# Criar da Tabela Descritiva
knitr::kable(date, align = 'cc', caption = "Tabela Descritiva",
col.names = c("Variáveis", "Média $\\pm$ sd", " CV(%)")) %>%
kable_classic(full_width = F, html_font = "Times", font_size = 16)| Variáveis | Média \(\pm\) sd | CV(%) |
|---|---|---|
| Poder Calorífico Superior (MJ/kg) | 17.50 \(\pm\) 0.18 | 1.02 |
| Extrativos | 1.99 \(\pm\) 0.71 | 35.78 |
| Lignina | 29.53 \(\pm\) 1.01 | 3.43 |
| Holocelulose | 68.48 \(\pm\) 1.39 | 2.03 |
y <- tabela3$PCS
scale(y) # padronização da variável ## [,1]
## [1,] 0.16212574
## [2,] 0.84462282
## [3,] 0.98582911
## [4,] -0.07321808
## [5,] -0.02614931
## [6,] 0.51514147
## [7,] 0.72695091
## [8,] 1.62125742
## [9,] 0.53867585
## [10,] -2.37958750
## [11,] -0.99105897
## [12,] -1.39114346
## [13,] -0.87338706
## [14,] -1.13226526
## [15,] -0.73218077
## [16,] -0.33209628
## [17,] -0.63804324
## [18,] -0.40269942
## [19,] -1.03812773
## [20,] -0.21442437
## [21,] 0.27979765
## [22,] 1.71539494
## [23,] 1.50358551
## [24,] 1.36237922
## [25,] -0.04968370
## [26,] -0.47330257
## [27,] 0.49160709
## attr(,"scaled:center")
## [1] 17.49837
## attr(,"scaled:scale")
## [1] 0.1777867
score_z <- function(y, media = NULL, despad = NULL) {if (is.null(media)) {
media <- mean(y)}
if (is.null(despad)) {despad <- sd(y)}
(y - media)/despad}
status <- ifelse(abs(score_z(y)) > 2, "outlier", "tipical") # ocorrência de outlier
table(status)## status
## outlier tipical
## 1 26
y <- tabela3$extrativos
scale(y) # padronização da variável ## [,1]
## [1,] 1.331445495
## [2,] 1.048749709
## [3,] 0.868664554
## [4,] -1.347198040
## [5,] -1.015117292
## [6,] -1.597505782
## [7,] -1.039899188
## [8,] -0.948612380
## [9,] -1.318383529
## [10,] -0.544544085
## [11,] -0.321781574
## [12,] -0.169108733
## [13,] 0.733169486
## [14,] -0.011163553
## [15,] -0.048094631
## [16,] -0.251250556
## [17,] -0.095328870
## [18,] -1.028834087
## [19,] -0.216364485
## [20,] -0.113852965
## [21,] -0.090932378
## [22,] 0.994138401
## [23,] 2.436436619
## [24,] 1.945278655
## [25,] -0.008672669
## [26,] 0.241888773
## [27,] 0.566873104
## attr(,"scaled:center")
## [1] 1.993663
## attr(,"scaled:scale")
## [1] 0.7133434
score_z <- function(y, media = NULL, despad = NULL) {if (is.null(media)) {
media <- mean(y)}
if (is.null(despad)) {despad <- sd(y)}
(y - media)/despad}
status <- ifelse(abs(score_z(y)) > 2, "outlier", "tipical") # ocorrência de outlier
table(status)## status
## outlier tipical
## 1 26
y <- tabela3$lignina
scale(y) # padronização da variável ## [,1]
## [1,] 0.3318672
## [2,] 0.4315091
## [3,] 1.2007107
## [4,] 0.9837564
## [5,] 0.2076259
## [6,] 0.2638626
## [7,] -0.3952338
## [8,] -0.2176548
## [9,] -1.0970325
## [10,] 0.1513780
## [11,] 0.4995639
## [12,] -0.3672771
## [13,] -1.8706458
## [14,] -1.7298169
## [15,] -1.2689705
## [16,] -0.2669823
## [17,] -0.3376925
## [18,] 0.7135992
## [19,] -1.0505316
## [20,] -0.7729587
## [21,] -1.4267870
## [22,] -0.3319350
## [23,] 1.8115447
## [24,] 0.7333263
## [25,] 1.0694917
## [26,] 1.4662866
## [27,] 1.2689963
## attr(,"scaled:center")
## [1] 29.52767
## attr(,"scaled:scale")
## [1] 1.013532
score_z <- function(y, media = NULL, despad = NULL) {if (is.null(media)) {
media <- mean(y)}
if (is.null(despad)) {despad <- sd(y)}
(y - media)/despad}
status <- ifelse(abs(score_z(y)) > 2, "outlier", "tipical") # ocorrência de outlier
table(status)## status
## tipical
## 27
y <- tabela3$holocelulose
scale(y) # padronização da variável ## [,1]
## [1,] -0.927465940
## [2,] -0.854870991
## [3,] -1.324430479
## [4,] -0.025999083
## [5,] 0.370436514
## [6,] 0.628920745
## [7,] 0.823805163
## [8,] 0.647056570
## [9,] 1.479993882
## [10,] 0.169479455
## [11,] -0.199595501
## [12,] 0.355428315
## [13,] 0.990075132
## [14,] 1.270038207
## [15,] 0.952210656
## [16,] 0.324379028
## [17,] 0.295852212
## [18,] 0.007684768
## [19,] 0.879116955
## [20,] 0.623510368
## [21,] 1.089592398
## [22,] -0.268789189
## [23,] -2.577357669
## [24,] -1.536648217
## [25,] -0.777213098
## [26,] -1.196115607
## [27,] -1.219094595
## attr(,"scaled:center")
## [1] 68.47867
## attr(,"scaled:scale")
## [1] 1.38672
score_z <- function(y, media = NULL, despad = NULL) {if (is.null(media)) {
media <- mean(y)}
if (is.null(despad)) {despad <- sd(y)}
(y - media)/despad}
status <- ifelse(abs(score_z(y)) > 2, "outlier", "tipical") # ocorrência de outlier
table(status)## status
## outlier tipical
## 1 26
par(mfrow=c(1,4))
boxplot(tabela3$extrativos, col="blue", main="Box Plot",
ylab= "Extrativos", adj=0.5, ylim=c(0,4))
boxplot(tabela3$lignina, col="purple",main="Box Plot",
ylab= "Lignina", adj=0.5, ylim=c(26,32))
boxplot(tabela3$holocelulose,col="green2",main="Box Plot", ylab= "Holocelulose",
adj=0.5, ylim=c(64,72))
boxplot(tabela3$PCS,col="gray",main="Box Plot", ylab= "PCS (MJ/kg)",
adj=0.5, ylim=c(17.0,17.8)) chart.Correlation(tabela3, histogram =TRUE)# Ajuste do modelo
modelo3<-lm(formula =PCS~-1+extrativos+lignina+holocelulose, data=tabela3)
modelo3##
## Call:
## lm(formula = PCS ~ -1 + extrativos + lignina + holocelulose,
## data = tabela3)
##
## Coefficients:
## extrativos lignina holocelulose
## 0.2244 0.2057 0.1603
# Estatísticas das estimativas dos paramentros do modelo
summary(modelo3)##
## Call:
## lm(formula = PCS ~ -1 + extrativos + lignina + holocelulose,
## data = tabela3)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.40514 -0.09816 0.00261 0.10095 0.34158
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## extrativos 0.224352 0.050789 4.417 0.000183 ***
## lignina 0.205672 0.024158 8.514 1.03e-08 ***
## holocelulose 0.160314 0.009798 16.361 1.61e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1687 on 24 degrees of freedom
## Multiple R-squared: 0.9999, Adjusted R-squared: 0.9999
## F-statistic: 9.678e+04 on 3 and 24 DF, p-value: < 2.2e-16
# Anova da regressão do modelo
anova(modelo3)## Analysis of Variance Table
##
## Response: PCS
## Df Sum Sq Mean Sq F value Pr(>F)
## extrativos 1 7376.7 7376.7 259062.87 < 2.2e-16 ***
## lignina 1 883.0 883.0 31011.91 < 2.2e-16 ***
## holocelulose 1 7.6 7.6 267.69 1.614e-14 ***
## Residuals 24 0.7 0.0
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
PCS3_est<- predict(modelo3)
resid<-(tabela3$PCS-PCS3_est)
Res2<-resid^2
SQResiduo<- sum(Res2)
Syx<-sqrt(SQResiduo/((length(tabela3$PCS))-3))
Syx_Porc<-(Syx/(mean(tabela3$PCS)))*100
Syx<-round(Syx,2)
Syx_Porc<-round(Syx_Porc, 2)
newdata33 = data.frame(Syx,Syx_Porc)
# Criar da Tabela Descritiva
knitr::kable(newdata33, align = 'cc',
caption = "Medidas de Precisão do Modelo",
col.names = c("S$_{yx}$", "S$_{yx}$%")) %>%
kable_classic(full_width = F, html_font = "Times", font_size = 16)| S\(_{yx}\) | S\(_{yx}\)% |
|---|---|
| 0.17 | 0.96 |
newdatas<-data.frame(extrativos= c(1.25),lignina= c(30), holocelulose= c(68))
PCS_estimado1 = predict(modelo3, newdatas, interval = "confidence");
PCS_estimado1 # Valores do limite de confiança dos valores preditos## fit lwr upr
## 1 17.35194 17.23403 17.46985
NORMALIDADE:
Ho: resíduos seguem distribuição normal;
Hi: resíduos não seguem distribuição normal
Resultado:
Valor de p > 0.05, não rejeita Ho para alfa=5%.
## Normalidade dos Resíduos
shapiro.test(modelo3$residuals)##
## Shapiro-Wilk normality test
##
## data: modelo3$residuals
## W = 0.98761, p-value = 0.981
ks.test(modelo3$residuals, "pnorm")##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: modelo3$residuals
## D = 0.37484, p-value = 0.0006472
## alternative hypothesis: two-sided
INDEPENDÊNCIA DOS RESÍDUOS:
Ho: resíduos são independentes;
Hi: resíduos não são independentes
Resultado:
Valor de p > 0.05, não rejeita Ho para alfa=5%.
## Independencia dos Resíduos (Durbin-Watson)
durbinWatsonTest(modelo3)## lag Autocorrelation D-W Statistic p-value
## 1 0.4867611 1.023195 0
## Alternative hypothesis: rho != 0
HOMOSCEDASTICIDADE DOS RESÍDUOS:
Ho: resíduos são homogênios;
Hi: resíduos não são homogênios;
Resultado:
Valor de p > 0.05, não rejeita Ho para alfa=5%.
## Homocedasticidade (Breusch-Pagan)
bptest(modelo3)##
## studentized Breusch-Pagan test
##
## data: modelo3
## BP = 1.326, df = 2, p-value = 0.5153
ncvTest(modelo3)## Non-constant Variance Score Test
## Variance formula: ~ fitted.values
## Chisquare = 1.173309, Df = 1, p = 0.27872
Valores em vermelho estimados; valores em azul observados.
PCS3_est<-predict.lm(modelo3)
newdata3 = data.frame(tabela3, PCS3_est)
Res<-(((newdata3$PCS-newdata3$PCS3_est)/(newdata3$PCS))*100)
newdata3 = data.frame(tabela3, PCS3_est,Res)
G1<-ggplot(newdata3) +
geom_point(size=2, aes(x=PCS, y=PCS3_est), color="red2")+
geom_abline(intercept = 0, slope = 1, color = "black")+
geom_point(size=2, aes(x=PCS3_est, y=PCS), color="blue2")+
theme_classic()+ # aparencia clean do gráfico
labs(x = "PCS Observada (MJ/kg)",
y = "PCS Estimada (Mj/kg)",
title = "Gráfico 1:1")+ # legendas
scale_x_continuous(breaks = seq(17.0, 18.0, 0.20), limits= c(17.0, 18.0))+
scale_y_continuous(breaks = seq(17.0, 18.0, 0.20), limits= c(17.0, 18.0))+
theme( plot.title = element_text(hjust = 0.5),
legend.title = element_text(hjust = 0.5))+ # centralizar títulos
theme(plot.title = element_text(size = 13, face = "bold"),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10)) # negrito nos títulos
G2<-ggplot(newdata3) +
geom_point(size=2, aes(x=PCS, y=Res)
,color="black")+ # gráfico de pontos
theme_classic()+ # aparencia clean do gráfico
labs(x = "PCS Observada (g/cm³)",
y = "Resíduo (%)",
title = "Gráfico de Resíduos")+ # legendas
scale_x_continuous(breaks = seq(17.0, 18.0, 0.20), limits= c(17.0, 18.0)) +
scale_y_continuous(breaks = seq(-30, 30, 10), limits= c(-30,30)) +
theme( plot.title = element_text(hjust = 0.5),
legend.title = element_text(hjust = 0.5))+ # centralizar títulos
theme(plot.title = element_text(size = 13, face = "bold"),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10))+ # negrito nos títulos
geom_hline(yintercept = 0, color="black")+ # linha no 0 do eixo y
theme(axis.title.y = element_text(angle = 90))
grid.arrange(G1,G2, ncol=1) De acordo com GROLEMUND (2018), a ciência de dados é uma área em crescimento.
A regressão não linear geralmente possui parâmetros interpretáveis (ROSSE; VENCOVSKY, 2000). Para CHEN et al. (2021), a análise multivariada é a melhor opção.