SADCAT para ROLES en Animales

Author

Alejandro Martínez-Mingo

SADCAT para Roles en Animales

Notebook de análisis del dataset ROLESTODO mediante el cálculo de las puntuaciones en distintas facetas y dimensiones de teoría de estereotipos a partir del diccionario SADCAT en español.

Este notebook está preparado para analizar el dataset de roles en animales. Comenzamos con su importación y análisis de estructura:

animales <- read_csv("dat/ROLESTODO_animales_descriptores_long.csv")
str(animales)
spc_tbl_ [73 × 6] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ CODIGO           : num [1:73] 101 102 103 104 105 106 107 108 109 110 ...
 $ TIPO_cuestionario: num [1:73] 1 1 1 1 1 1 1 1 1 1 ...
 $ item             : chr [1:73] "PA1.ANIMAL_CANICHE" "PA1.ANIMAL_CANICHE" "PA1.ANIMAL_CANICHE" "PA1.ANIMAL_CANICHE" ...
 $ descripcion      : chr [1:73] "Pequeño, chillón, Molesto, irritable, feo, rata, patada, gruñón, abuela, pija" "Pequeño, Agresivo, Ruidoso, Feo, Cabezón, Adorable" "Infantil, Pijo y adinerado, Como una rata, Poca personalidad, Tonto" "Mono, Cobarde, Débil, Vulnerable, Achuchable, Bonito, Amariconado" ...
 $ fase             : chr [1:73] "PA1" "PA1" "PA1" "PA1" ...
 $ target           : chr [1:73] "ANIMAL_CANICHE" "ANIMAL_CANICHE" "ANIMAL_CANICHE" "ANIMAL_CANICHE" ...
 - attr(*, "spec")=
  .. cols(
  ..   CODIGO = col_double(),
  ..   TIPO_cuestionario = col_double(),
  ..   item = col_character(),
  ..   descripcion = col_character(),
  ..   fase = col_character(),
  ..   target = col_character()
  .. )
 - attr(*, "problems")=<externalptr> 

División de descriptores

Las descripciones quedan definidas en la columna descripcion del dataset y están separadas por ,. Se ha diseñado una función en el script Data.R, ya importado a este notebook en la inicialización, para separar los descriptores y limpiarlos. Aplicamos la función:

library(udpipe)

m <- udpipe_download_model(language = "spanish")
ud_model <- udpipe_load_model(m$file_model)

animales_split <- split_descriptors(animales,input_type = "data", desc_col = "descripcion", lemmatize = "both", udpipe_model = ud_model)

Accediendo a la cabecera del dataset vemos que los descriptores aparecen cada uno en una columna, eliminando acentos, mayúsculas y caraceteres especiales, y uniendo los n_gramas (SADCAT está diseñado para evaluar n_gramas unidos).

head(animales_split)

Análisis de cobertura global

Posteriormente, se aplica una función definida en Dictionary.R para analizar el coverage global del diccionario. Esto nos permite analizar qué descripciones son quedan mejor representadas en el diccionario SADCAT en español, y nos permitirá más adelante evaluar la posible eliminación de casos, o la limpieza de los descriptores. Un ejemplo de esto puede ser el caso 124, si nos fijamos, tiene 6 descriptores y una cobertura del 0%. Esto sucede porque utiliza el plural en todos sus descriptores, y la función dict_coverage() aún no tiene implementada una solución a este problema. Este tipo de situaciones deben de quedar documentadas para realizar los cambios pertinentes en las funciones.

animales_cov <- dict_coverage(animales_split, prefix = "descriptor_")
animales_cov

Análisis de cobertura por dimensión

A continuación, se utiliza la función dict_dim_coverage_all() para combrobar la cobertura de cada dimensión y faceta del diccionario por separado en cada uno de los casos. Los resultados muestran una baja cobertura en la mayoría de las facetas. En muchos casos, esto puede ser normal, ya que la tarea no fué diseñada para evaluar dichas facetas.

animales_cov_dims <- dict_dim_coverage_all(animales_cov, prefix = "descriptor_")

Para evaluar la cobertura de las dimensiones y facetas con mayor precisión, a continuación se prepara un bloque de resumen de la cobertura media (media por casos) para cada uno de estos elementos. Se ordena de forma descendente.

cov_cols <- grep("^cov_", names(animales_cov_dims), value = TRUE)

m <- colMeans(animales_cov_dims[, cov_cols, drop = FALSE], na.rm = TRUE)

means_cov <- data.frame(
  variable = names(m),
  mean_coverage = as.numeric(m),
  row.names = NULL
)

means_cov <- means_cov[order(means_cov$mean_coverage, decreasing = TRUE), ]
means_cov

Cálculo de dirección para cada dimensión y faceta

Finalmente, se calcula la dirección media en cada faceta y dimensión. Este procedimiento está definido en la función dict_dim_dirmean_all() en el script Dictionary.R que ya ha sido importado en el cuaderno. El procedimiento utilizado es el recomendado por Gandalf Nicolás, documentado en (referencia SADCAT):

Para cada fila (p. ej., un animal descrito por varios descriptor_n) y para cada dimensión X_dir del diccionario, tomamos solo los descriptores que:

  1. aparecen en SADCAT::Spanishdicts$Palabra, y
  2. tienen un valor no-NA en X_dir (típicamente -1, 0 o 1).

Entonces:

\[ dirmean_X = \text{mean}(X\_dir) \in [-1,1] \]

Si una fila no tiene ningún descriptor aplicable a esa dimensión, dirmean_X = NA.

Resultados esperables:

  • dirmean_X ≈ 1 → todos los descriptores aplicables son “alto” en X.
  • dirmean_X ≈ -1 → todos los descriptores aplicables son “bajo” en X.
  • dirmean_X ≈ 0 → mezcla de altos y bajos (o presencia de neutros si el diccionario usa 0).
  • dirmean_X = NA → no hay evidencia para esa dimensión (ningún descriptor con X_dir no-NA).
animales_con_dirmean <- dict_dim_dirmean_all(animales_cov_dims, prefix = "descriptor_")

A continuación se prepara un bloque de análisis de los resultados en los que se pueden ver los descriptivos de cobertura, dirección media, y número de descriptores que contribuyen a estimar esta dirección media.

Descriptivos de cobertura, dirección y ocurrencias

cov_cols     <- grep("^cov_",     names(animales_con_dirmean), value = TRUE)
dirmean_cols <- grep("^dirmean_", names(animales_con_dirmean), value = TRUE)
n_cols       <- grep("^n_dirmean_", names(animales_con_dirmean), value = TRUE)
summary_block <- function(df, cols) {
  x <- df[, cols, drop = FALSE]
  out <- data.frame(
    variable = cols,
    n = sapply(x, function(z) sum(!is.na(z))),
    na = sapply(x, function(z) sum(is.na(z))),
    mean = sapply(x, function(z) mean(z, na.rm = TRUE)),
    sd = sapply(x, function(z) sd(z, na.rm = TRUE)),
    min = sapply(x, function(z) min(z, na.rm = TRUE)),
    q25 = sapply(x, function(z) quantile(z, 0.25, na.rm = TRUE, names = FALSE)),
    median = sapply(x, function(z) median(z, na.rm = TRUE)),
    q75 = sapply(x, function(z) quantile(z, 0.75, na.rm = TRUE, names = FALSE)),
    max = sapply(x, function(z) max(z, na.rm = TRUE)),
    row.names = NULL
  )
  out
}

cov_summary     <- summary_block(animales_con_dirmean, cov_cols)
dirmean_summary <- summary_block(animales_con_dirmean, dirmean_cols)
n_summary       <- summary_block(animales_con_dirmean, n_cols)

cov_summary[order(cov_summary$mean, decreasing = TRUE), ]
dirmean_summary[order(abs(dirmean_summary$mean), decreasing = TRUE), ] 
n_summary[order(n_summary$mean, decreasing = TRUE), ]

Guardado de los datos

Exportamos el dataset con toda la información para continuar con en análisis predictivo a partir de los modelos lineales en los siguientes bloques.

write.csv(
  animales_con_dirmean,
  file = "./dat/animales_SADCAT.csv",
  row.names = FALSE,
  fileEncoding = "UTF-8"
)

Modelado de dimensiones de competencia y cordialidad

Importamos tanto el dataset guardado, como el dataset con las puntuaciones de los participantes en la investigación. (en este punto habría que documentar bien qué significa cada variable en el dataset de ROLESTODO)

path_roles  <- "./dat/ROLESTODO_animales_scores.csv"
path_sadcat <- "./dat/animales_SADCAT.csv"

roles  <- read_csv(path_roles,  show_col_types = FALSE)
sadcat <- read_csv(path_sadcat, show_col_types = FALSE)

El dataset sadcat está en modo “long” porque resultaba más sencillo aplicar las funciones de cálculo de dirección y cobertura, pero para realizar los análisis predictivos debemos de ponerlo en modo “wide”. Esto lo hacemos en el siguiente bloque.

# Claves de unión (usa TIPO_cuestionario solo si está en ambos)
by_keys <- "CODIGO"
if ("TIPO_cuestionario" %in% names(roles) && "TIPO_cuestionario" %in% names(sadcat)) {
  by_keys <- c("CODIGO", "TIPO_cuestionario")
}

# Recodifica target a un sufijo limpio
# (evitamos acentos y nombres largos en columnas)
sadcat_wide <- sadcat %>%
  mutate(animal = case_when(
    str_detect(target, "CANICHE") ~ "caniche",
    str_detect(target, "COLIBR")  ~ "colibri",
    TRUE ~ make.names(target)
  )) %>%
  select(-target) %>%
  pivot_wider(
    id_cols    = all_of(by_keys),
    names_from = animal,
    values_from = -c(all_of(by_keys), animal),
    names_glue = "{.value}_{animal}",
    values_fn  = dplyr::first   # <- clave: devuelve un valor escalar, no una lista
  )

# 2) Une al dataset de roles (mantiene CODIGO y todo lo de roles)
df_roles_sadcat <- roles %>%
  left_join(sadcat_wide, by = by_keys)

Una vez disponemos del dataset df_roles_sadcat en el formato adecuado, podemos estimar los modelos de regresión simple para cada faceta o dimensión. A continuación se pueden ver algunos ejemplos con las dimensiones de cordialidad y competencia.

# Caniche
m_cord_caniche <- lm(cordialidad_caniche ~ dirmean_Warmth_caniche,
                     data = df_roles_sadcat, na.action = na.exclude)

m_comp_caniche <- lm(competencia_caniche ~ dirmean_Competence_caniche,
                     data = df_roles_sadcat, na.action = na.exclude)

# Colibrí
m_cord_colibri <- lm(cordialidad_colibri ~ dirmean_Warmth_colibri,
                     data = df_roles_sadcat, na.action = na.exclude)

m_comp_colibri <- lm(competencia_colibri ~ dirmean_Competence_colibri,
                     data = df_roles_sadcat, na.action = na.exclude)
# Ver resultados
summary(m_cord_caniche)

Call:
lm(formula = cordialidad_caniche ~ dirmean_Warmth_caniche, data = df_roles_sadcat, 
    na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.0396 -1.2385 -0.0481  1.0111  3.4732 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)              4.0310     0.2619  15.392  < 2e-16 ***
dirmean_Warmth_caniche   2.0171     0.3893   5.182 9.98e-06 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.558 on 34 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.4413,    Adjusted R-squared:  0.4248 
F-statistic: 26.85 on 1 and 34 DF,  p-value: 9.981e-06
summary(m_comp_caniche)

Call:
lm(formula = competencia_caniche ~ dirmean_Competence_caniche, 
    data = df_roles_sadcat, na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.2922 -0.9590 -0.1258  0.9022  2.7074 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  3.6258     0.3689   9.829 1.99e-08 ***
dirmean_Competence_caniche   0.3336     0.4345   0.768    0.453    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.441 on 17 degrees of freedom
  (18 observations deleted due to missingness)
Multiple R-squared:  0.03351,   Adjusted R-squared:  -0.02334 
F-statistic: 0.5895 on 1 and 17 DF,  p-value: 0.4532
summary(m_cord_colibri)

Call:
lm(formula = cordialidad_colibri ~ dirmean_Warmth_colibri, data = df_roles_sadcat, 
    na.action = na.exclude)

Residuals:
   Min     1Q Median     3Q    Max 
-3.107 -0.607 -0.107  1.393  2.408 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)              4.4492     0.5425   8.201 2.29e-09 ***
dirmean_Warmth_colibri   0.1578     0.6096   0.259    0.797    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.473 on 32 degrees of freedom
  (3 observations deleted due to missingness)
Multiple R-squared:  0.00209,   Adjusted R-squared:  -0.02909 
F-statistic: 0.06701 on 1 and 32 DF,  p-value: 0.7974
summary(m_comp_colibri)

Call:
lm(formula = competencia_colibri ~ dirmean_Competence_colibri, 
    data = df_roles_sadcat, na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.7361 -1.1014  0.3986  0.8986  1.3986 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  4.2361     0.3683  11.503 5.28e-10 ***
dirmean_Competence_colibri   0.8653     0.4207   2.057   0.0537 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.103 on 19 degrees of freedom
  (16 observations deleted due to missingness)
Multiple R-squared:  0.1821,    Adjusted R-squared:  0.139 
F-statistic:  4.23 on 1 and 19 DF,  p-value: 0.05371
# Ver gráficos de residuos (comentado para el render)
# plot(m_cord_caniche)
# plot(m_comp_caniche)
# plot(m_cord_colibri)
# plot(m_comp_colibri)

Vamos a filtrar solo casos con un coverage mayor a cierto punto de corte para ver si cambian los resultados con datos más fiables:

# Convierte un umbral en % (p.ej., 30) a escala del vector (0-100 o 0-1)
.coverage_threshold <- function(v, thr_pct) {
  v <- v[!is.na(v)]
  if (length(v) == 0) return(NA_real_)
  if (max(v) <= 1) thr_pct / 100 else thr_pct
}

# Filtra df por una columna de coverage con umbral en porcentaje (thr_pct)
filter_by_coverage <- function(df, coverage_col, thr_pct) {
  stopifnot(is.data.frame(df), coverage_col %in% names(df))
  thr <- .coverage_threshold(df[[coverage_col]], thr_pct)
  if (is.na(thr)) return(df[0, , drop = FALSE])  # todo NA -> 0 filas
  df[!is.na(df[[coverage_col]]) & df[[coverage_col]] >= thr, , drop = FALSE]
}
  1. CASO A: Filtrado por coverage GLOBAL (>= 30%)
  • Modelo: filtrar por cov_pct_global_modelo
  • Deportista: filtrar por cov_pct_global_mdeportista
df_global30_colibri      <- filter_by_coverage(df_roles_sadcat, "cov_pct_global_colibri", 30)
df_global30_caniche <- filter_by_coverage(df_roles_sadcat, "cov_pct_global_caniche", 30)

# colibris (global >= 30%)
m_cord_colibri_g30 <- lm(cordialidad_colibri ~ dirmean_Warmth_colibri,
                        data = df_global30_colibri, na.action = na.exclude)

m_comp_colibri_g30 <- lm(competencia_colibri ~ dirmean_Competence_colibri,
                        data = df_global30_colibri, na.action = na.exclude)

m_cord_caniche_g30 <- lm(cordialidad_caniche ~ dirmean_Warmth_caniche,
                      data = df_global30_caniche, na.action = na.exclude)

m_comp_caniche_g30 <- lm(competencia_caniche ~ dirmean_Competence_caniche,
                      data = df_global30_caniche, na.action = na.exclude)

# Ver resultados (global >= 30%)
summary(m_cord_colibri_g30)

Call:
lm(formula = cordialidad_colibri ~ dirmean_Warmth_colibri, data = df_global30_colibri, 
    na.action = na.exclude)

Residuals:
   Min     1Q Median     3Q    Max 
-3.107 -0.607 -0.107  1.393  2.408 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)              4.4492     0.5425   8.201 2.29e-09 ***
dirmean_Warmth_colibri   0.1578     0.6096   0.259    0.797    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.473 on 32 degrees of freedom
  (2 observations deleted due to missingness)
Multiple R-squared:  0.00209,   Adjusted R-squared:  -0.02909 
F-statistic: 0.06701 on 1 and 32 DF,  p-value: 0.7974
summary(m_comp_colibri_g30)

Call:
lm(formula = competencia_colibri ~ dirmean_Competence_colibri, 
    data = df_global30_colibri, na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.7361 -1.1014  0.3986  0.8986  1.3986 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  4.2361     0.3683  11.503 5.28e-10 ***
dirmean_Competence_colibri   0.8653     0.4207   2.057   0.0537 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.103 on 19 degrees of freedom
  (15 observations deleted due to missingness)
Multiple R-squared:  0.1821,    Adjusted R-squared:  0.139 
F-statistic:  4.23 on 1 and 19 DF,  p-value: 0.05371
summary(m_cord_caniche_g30)

Call:
lm(formula = cordialidad_caniche ~ dirmean_Warmth_caniche, data = df_global30_caniche, 
    na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.0589 -1.2778 -0.1254  1.0168  3.5408 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)              3.9924     0.2823  14.141 4.60e-15 ***
dirmean_Warmth_caniche   2.1330     0.4290   4.972 2.33e-05 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.605 on 31 degrees of freedom
Multiple R-squared:  0.4437,    Adjusted R-squared:  0.4257 
F-statistic: 24.72 on 1 and 31 DF,  p-value: 2.325e-05
summary(m_comp_caniche_g30)

Call:
lm(formula = competencia_caniche ~ dirmean_Competence_caniche, 
    data = df_global30_caniche, na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.5146 -1.0146  0.1048  0.9854  2.7000 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  3.7049     0.3838   9.654 7.93e-08 ***
dirmean_Competence_caniche   0.1903     0.4627   0.411    0.687    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.472 on 15 degrees of freedom
  (16 observations deleted due to missingness)
Multiple R-squared:  0.01115,   Adjusted R-squared:  -0.05478 
F-statistic: 0.1691 on 1 and 15 DF,  p-value: 0.6867
  1. CASO B: Filtrado por coverage ESPECÍFICO por análisis (>= 20%)

    • Cordialidad Modelo: cov_Warmth_dict_pct_modelo
    • Competencia Modelo: cov_Competence_dict_pct_modelo
    • Cordialidad Deport.: cov_Warmth_dict_pct_mdeportista
    • Competencia Deport.: cov_Competence_dict_pct_mdeportista
df_warmth20_colibri      <- filter_by_coverage(df_roles_sadcat, "cov_Warmth_dict_pct_colibri", 20)
df_comp20_colibri        <- filter_by_coverage(df_roles_sadcat, "cov_Competence_dict_pct_colibri", 20)

df_warmth20_caniche <- filter_by_coverage(df_roles_sadcat, "cov_Warmth_dict_pct_caniche", 20)
df_comp20_caniche   <- filter_by_coverage(df_roles_sadcat, "cov_Competence_dict_pct_caniche", 20)

# colibris (específico >= 20%)
m_cord_colibri_w20 <- lm(cordialidad_colibri ~ dirmean_Warmth_colibri,
                        data = df_warmth20_colibri, na.action = na.exclude)

m_comp_colibri_c20 <- lm(competencia_colibri ~ dirmean_Competence_colibri,
                        data = df_comp20_colibri, na.action = na.exclude)

m_cord_caniche_w20 <- lm(cordialidad_caniche ~ dirmean_Warmth_caniche,
                      data = df_warmth20_caniche, na.action = na.exclude)

m_comp_caniche_c20 <- lm(competencia_caniche ~ dirmean_Competence_caniche,
                      data = df_comp20_caniche, na.action = na.exclude)

# Ver resultados (específico >= 20%)
summary(m_cord_colibri_w20)

Call:
lm(formula = cordialidad_colibri ~ dirmean_Warmth_colibri, data = df_warmth20_colibri, 
    na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.2360 -0.7360 -0.1545  1.2640  2.2911 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)              4.4519     0.5289   8.418 2.15e-09 ***
dirmean_Warmth_colibri   0.2841     0.5991   0.474    0.639    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.436 on 30 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.007437,  Adjusted R-squared:  -0.02565 
F-statistic: 0.2248 on 1 and 30 DF,  p-value: 0.6388
summary(m_comp_colibri_c20)

Call:
lm(formula = competencia_colibri ~ dirmean_Competence_colibri, 
    data = df_comp20_colibri, na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.9254 -0.7517  0.3246  0.7483  1.2483 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  4.4254     0.3857  11.475 1.66e-08 ***
dirmean_Competence_colibri   0.8263     0.4437   1.862   0.0837 .  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.082 on 14 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.1986,    Adjusted R-squared:  0.1413 
F-statistic: 3.469 on 1 and 14 DF,  p-value: 0.08366
summary(m_cord_caniche_w20)

Call:
lm(formula = cordialidad_caniche ~ dirmean_Warmth_caniche, data = df_warmth20_caniche, 
    na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.1440 -1.2857 -0.1470  0.9426  3.6505 

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)              3.9476     0.3073   12.84 2.95e-13 ***
dirmean_Warmth_caniche   2.3927     0.5247    4.56 9.21e-05 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.656 on 28 degrees of freedom
Multiple R-squared:  0.4262,    Adjusted R-squared:  0.4057 
F-statistic:  20.8 on 1 and 28 DF,  p-value: 9.214e-05
summary(m_comp_caniche_c20)

Call:
lm(formula = competencia_caniche ~ dirmean_Competence_caniche, 
    data = df_comp20_caniche, na.action = na.exclude)

Residuals:
    Min      1Q  Median      3Q     Max 
-1.4085 -0.9085 -0.4085  0.4782  2.3014 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                  3.9085     0.4693   8.328 7.04e-05 ***
dirmean_Competence_caniche   0.5801     0.7325   0.792    0.454    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.379 on 7 degrees of freedom
Multiple R-squared:  0.08224,   Adjusted R-squared:  -0.04887 
F-statistic: 0.6273 on 1 and 7 DF,  p-value: 0.4544