R Markdown

# Establecer directorio de trabajo
setwd("C:/OSCAR/RESPALDO CESAR/OSCAR/CURSOS/R DGTIC OCT 2025/e4")
getwd()
## [1] "C:/OSCAR/RESPALDO CESAR/OSCAR/CURSOS/R DGTIC OCT 2025/e4"
# Paquetes a utilizar

library("tidyverse")
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.1     ✔ stringr   1.5.2
## ✔ ggplot2   4.0.0     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── 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("stringr")
library("dplyr")
library("forcats")
library("janitor")
## 
## Adjuntando el paquete: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library("lubridate")
library("graphics")
library("ggplot2")

# Se utilizará el archivo a4_iris.csv para el análisis
# Para leer archivos externos, importacion de datos. Se usa clean_names para cambiar el punto por guión bajo en los nombres de las variables
data_iris <- read.csv("C:/OSCAR/RESPALDO CESAR/OSCAR/CURSOS/R DGTIC OCT 2025/e4/a4_iris.csv", header=TRUE, sep=",")
data_iris <- clean_names(data_iris)
# Revisamos la estructura del archivo
str(data_iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ sepal_length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ sepal_width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ petal_length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ petal_width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ variety     : chr  "Setosa" "Setosa" "Setosa" "Setosa" ...
names(data_iris)
## [1] "sepal_length" "sepal_width"  "petal_length" "petal_width"  "variety"
# Se usa la funcion summary para obtener las estadísticas básicas sin discriminar por la variedad
summary(data_iris)
##   sepal_length    sepal_width     petal_length    petal_width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##    variety         
##  Length:150        
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Se plantea la siguiente pregunta: ¿Hay relación entre el largo y ancho del sepalo?

Analisis global sin considerar la variedad de especies de flor.

#   Se calcula la recta ajustada con la funcion lm
rectaSep=lm(data_iris$sepal_width ~ data_iris$sepal_length)
rectaSep
## 
## Call:
## lm(formula = data_iris$sepal_width ~ data_iris$sepal_length)
## 
## Coefficients:
##            (Intercept)  data_iris$sepal_length  
##                3.41895                -0.06188
# Grafica de dispersion
ggplot(data_iris, aes(x = sepal_length, y = sepal_width)) +
  geom_point(alpha = 0.6, size = 3) +
  geom_smooth(method = "lm", se = FALSE, color = "blue") + # Añade la recta ajustada
  labs(title = "Longitud vs Ancho",
       subtitle = "Sépalo",
       x = "Longitud",
       y = "Ancho") +
  theme_classic()
## `geom_smooth()` using formula = 'y ~ x'

# Identificamos los elementos de la regresion
names(rectaSep)
##  [1] "coefficients"  "residuals"     "effects"       "rank"         
##  [5] "fitted.values" "assign"        "qr"            "df.residual"  
##  [9] "xlevels"       "call"          "terms"         "model"
# Revisamos las estadisticas de la regresion
summary(rectaSep)
## 
## Call:
## lm(formula = data_iris$sepal_width ~ data_iris$sepal_length)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1.1095 -0.2454 -0.0167  0.2763  1.3338 
## 
## Coefficients:
##                        Estimate Std. Error t value Pr(>|t|)    
## (Intercept)             3.41895    0.25356   13.48   <2e-16 ***
## data_iris$sepal_length -0.06188    0.04297   -1.44    0.152    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4343 on 148 degrees of freedom
## Multiple R-squared:  0.01382,    Adjusted R-squared:  0.007159 
## F-statistic: 2.074 on 1 and 148 DF,  p-value: 0.1519
# Intervalo de confianza de los coeficientes al 95% de confianza
confint(rectaSep)
##                             2.5 %     97.5 %
## (Intercept)             2.9178767 3.92001694
## data_iris$sepal_length -0.1467928 0.02302323

Podemos notar que los datos están muy dispersos y no se ajustan a una recta.

Tenemos una R² = 0.0138, es decir que la varianza explicada por el modelo es muy pobre, además que el valor de la estadística F es muy pequeño con un p-value = 0.1519 es mayor a una significancia del 5%, por lo que no se rechazaría la hipótesis nula que beta = 0. El coeficiente de confianza para beta confirma que el intervalo cruza por el cero. Entonces podemos concluir que no se observa una relación lineal significativa entre el largo y el ancho del sépalo.

A continuación se realiza el mismo análisis para la longitud y ancho del pétalo.

#   Se calcula la recta ajustada con la funcion lm
rectaPet=lm(data_iris$petal_width ~ data_iris$petal_length)
rectaPet
## 
## Call:
## lm(formula = data_iris$petal_width ~ data_iris$petal_length)
## 
## Coefficients:
##            (Intercept)  data_iris$petal_length  
##                -0.3631                  0.4158
# Grafica de dispersion
ggplot(data_iris, aes(x = petal_length, y = petal_width)) +
  geom_point(alpha = 0.6, size = 3) +
  geom_smooth(method = "lm", se = FALSE, color = "red") + # Añade la recta ajustada
  labs(title = "Longitud vs Ancho",
       subtitle = "Pétalo",
       x = "Longitud",
       y = "Ancho") +
  theme_classic()
## `geom_smooth()` using formula = 'y ~ x'

# Identificamos los elementos de la regresion
names(rectaPet)
##  [1] "coefficients"  "residuals"     "effects"       "rank"         
##  [5] "fitted.values" "assign"        "qr"            "df.residual"  
##  [9] "xlevels"       "call"          "terms"         "model"
# Revisamos las estadisticas de la regresion
summary(rectaPet)
## 
## Call:
## lm(formula = data_iris$petal_width ~ data_iris$petal_length)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.56515 -0.12358 -0.01898  0.13288  0.64272 
## 
## Coefficients:
##                         Estimate Std. Error t value Pr(>|t|)    
## (Intercept)            -0.363076   0.039762  -9.131  4.7e-16 ***
## data_iris$petal_length  0.415755   0.009582  43.387  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.2065 on 148 degrees of freedom
## Multiple R-squared:  0.9271, Adjusted R-squared:  0.9266 
## F-statistic:  1882 on 1 and 148 DF,  p-value: < 2.2e-16
# Intervalo de confianza de los coeficientes al 95% de confianza
confint(rectaPet)
##                             2.5 %     97.5 %
## (Intercept)            -0.4416501 -0.2845010
## data_iris$petal_length  0.3968193  0.4346915

En este caso se nota claramente que los datos siguen una recta, de hecho la separación en dos grupos nos anticipa que también hay, al menos en este punto del análisis, diferenciación por especie.

Tenemos una R² = 0.9271 bastante aceptable, es decir que el modelo explica un 93% de la varianza, se refuerza con una estadística F muy grande (1882) y evidentemente un p-value para efectos prácticos de cero.Entonces podemos concluir que nuestro modelo tiene una evidente relación lineal entre el largo y el ancho del pétalo.

Ahora se realizará el análisis considerando la variedad por separado.

# Regresion lneal considerando la variedad por separado para el sepalo
by(data_iris, data_iris$variety,
   function(subdata) lm(sepal_width ~ sepal_length, data = subdata))
## data_iris$variety: Setosa
## 
## Call:
## lm(formula = sepal_width ~ sepal_length, data = subdata)
## 
## Coefficients:
##  (Intercept)  sepal_length  
##      -0.5694        0.7985  
## 
## ------------------------------------------------------------ 
## data_iris$variety: Versicolor
## 
## Call:
## lm(formula = sepal_width ~ sepal_length, data = subdata)
## 
## Coefficients:
##  (Intercept)  sepal_length  
##       0.8721        0.3197  
## 
## ------------------------------------------------------------ 
## data_iris$variety: Virginica
## 
## Call:
## lm(formula = sepal_width ~ sepal_length, data = subdata)
## 
## Coefficients:
##  (Intercept)  sepal_length  
##       1.4463        0.2319
# Grafica de dispersion por variedad
ggplot(data_iris, aes(x = sepal_length, y = sepal_width, color = variety)) +
  geom_point(alpha = 0.6, size = 3) +
  scale_color_manual(
    values=c("red","green","blue"))+
  labs(title = "Longitud vs Ancho",
       subtitle = "Sépalo",
       x = "Longitud",
       y = "Ancho",
       color = "Variedad") +
  theme_classic()

# Grafica de dispersion por variedad para el sepalo
ggplot(data_iris, aes(x = sepal_length, y = sepal_width, color = variety)) +
  geom_point(size = 2) +
  facet_grid(variety ~ .)

# Gráfica de dispersión
ggplot(data_iris, aes(x = petal_length, y = petal_width, color = variety)) +
  geom_point(alpha = 0.6, size = 3, ) +
  scale_color_manual(
    values=c("red","green","blue"))+
  labs(title = "Longitud vs Ancho",
       subtitle = "Pétalo",
       x = "Longitud",
       y = "Ancho",
       color = "Variedad") +
  theme_classic()

En el caso del sépalo se puede observar que los coeficientes beta de cada variedad aumentaron comparados con el valor de beta global para esta especie, si se observan de manera separada se puede notar con mayor claridad que la setosa tiene una beta mayor y si bien no tienen versicolor y virginica no tienen un valor de beta elevado, si permiten ajustar un modelo lineal.

En el caso del pétalo, desde el análisis global se percibe que tiene un buen ajuste lineal, mismo que se mantiene cuando se tratan las variedades por separado.