-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterpretaciones-estadisticas.js
More file actions
603 lines (526 loc) · 41.1 KB
/
Copy pathinterpretaciones-estadisticas.js
File metadata and controls
603 lines (526 loc) · 41.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
// ========================================
// MÓDULO DE INTERPRETACIONES ESTADÍSTICAS
// Sistema de interpretación dinámica basada en resultados
// Redacción de nivel profesional: terminología precisa (lineal vs. monotónica),
// reporte estilo APA, tamaño del efecto, IC 95%, potencia y salvaguardas.
// ========================================
const InterpretacionesEstadisticas = {
// ----------------------------------------
// Utilidades internas de formato
// ----------------------------------------
// ¿El coeficiente usado es Spearman? (el analizador guarda 'Spearman (Rho)')
_esSpearman(tipoCorrelacion) {
return typeof tipoCorrelacion === 'string' && tipoCorrelacion.includes('Spearman');
},
// p-valor con criterio profesional: nunca reportar p = 0.000
_fmtP(p) {
if (!Number.isFinite(p)) return 'p no disponible';
return p < 0.001 ? 'p < 0.001' : `p = ${p.toFixed(3)}`;
},
_fmtNum(x, dec = 3) {
return Number.isFinite(x) ? x.toFixed(dec) : '—';
},
// Conjunción española correcta: "y" → "e" ante palabras que inician con i/hi
_conj(siguientePalabra) {
return /^h?i(?![eé])/i.test(String(siguientePalabra).trim()) ? 'e' : 'y';
},
// Punto de corte de Cohen (1988) para correlaciones: .10 / .30 / .50
_benchmarkCohen(rAbs) {
if (rAbs < 0.1) return 'inferior al umbral de efecto pequeño';
if (rAbs < 0.3) return 'pequeño';
if (rAbs < 0.5) return 'mediano';
return 'grande';
},
// ========================================
// INTERPRETACIONES DE NORMALIDAD
// ========================================
generarInterpretacionNormalidad(var1, var2, resultado) {
const n = resultado.n;
const norm1 = resultado.normalidad1;
const norm2 = resultado.normalidad2;
// Símbolo del estadístico según la prueba: W para Shapiro-Wilk,
// D para Kolmogorov-Smirnov (Lilliefors).
const simbolo = norm => (norm.prueba && norm.prueba.includes('Shapiro')) ? 'W' : 'D';
const prueba = norm1.prueba; // Ambas variables usan la misma prueba (mismo n)
const esShapiro = prueba && prueba.includes('Shapiro');
// Reporte breve por variable, estilo APA
const rep = (nombre, norm) =>
`${nombre}: ${simbolo(norm)} = ${this._fmtNum(norm.estadistico)}, ${this._fmtP(norm.pValor)}`;
let texto = '';
// 1) Método y justificación de su elección
texto += `Se evaluó el supuesto de normalidad de ${var1} y ${var2} mediante la prueba de ${prueba}, `;
texto += esShapiro
? `seleccionada por tratarse de una muestra pequeña (n = ${n} < 50), contexto en el que Shapiro-Wilk presenta la mayor potencia estadística para detectar desviaciones de la normalidad (Razali y Wah, 2011). `
: `seleccionada por el tamaño de la muestra (n = ${n} ≥ 50), rango en el que Kolmogorov-Smirnov con la corrección de Lilliefors es el procedimiento de referencia. `;
texto += `El criterio de decisión fue: p > 0.05 indica que la distribución no se desvía significativamente de la normal. `;
// 2) Resultados por variable y 3) consecuencia metodológica
if (norm1.normal && norm2.normal) {
texto += `Los resultados mostraron que ambas variables cumplieron el supuesto (${rep(var1, norm1)}; ${rep(var2, norm2)}); en ambos casos p > 0.05, por lo que se retiene la hipótesis de normalidad. `;
texto += `En consecuencia, corresponde el uso de estadística paramétrica: se aplicó el coeficiente de correlación de Pearson (r), que cuantifica la relación LINEAL entre las variables y constituye el estimador de mayor potencia cuando la normalidad se satisface (Hernández-Sampieri y Mendoza, 2023). `;
} else if (!norm1.normal && !norm2.normal) {
texto += `Los resultados mostraron que ambas variables se desviaron significativamente de la normalidad (${rep(var1, norm1)}; ${rep(var2, norm2)}); en ambos casos p ≤ 0.05, incumpliéndose el supuesto exigido por la estadística paramétrica. `;
texto += `En consecuencia, se empleó el coeficiente de correlación de Spearman (ρ), un método no paramétrico basado en rangos que no requiere normalidad y cuantifica la relación MONOTÓNICA entre las variables, evitando así conclusiones distorsionadas por la forma de las distribuciones (Hernández-Sampieri y Mendoza, 2023). `;
} else {
const varNoNormal = !norm1.normal ? var1 : var2;
const normNoNormal = !norm1.normal ? norm1 : norm2;
const varNormal = norm1.normal ? var1 : var2;
const normNormal = norm1.normal ? norm1 : norm2;
texto += `Los resultados fueron mixtos: ${varNoNormal} se desvió significativamente de la normalidad (${rep(varNoNormal, normNoNormal)}, p ≤ 0.05), mientras que ${varNormal} sí cumplió el supuesto (${rep(varNormal, normNormal)}, p > 0.05). `;
texto += `Dado que el coeficiente de Pearson exige normalidad en AMBAS variables, basta con que una la incumpla para que el procedimiento paramétrico deje de ser apropiado. `;
texto += `Por ello se optó por el coeficiente de correlación de Spearman (ρ), que al operar sobre rangos es robusto frente a desviaciones de la normalidad y a valores extremos. `;
}
// 4) Recomendación de corroboración visual
texto += `La inspección de los gráficos Q-Q respalda visualmente esta decisión, en tanto los puntos se alinean sobre la recta de referencia.`;
return texto;
},
// ========================================
// INTERPRETACIONES DE CORRELACIÓN
// ========================================
generarInterpretacionCorrelacion(var1, var2, resultado) {
const coef = resultado.coeficiente;
const pValor = resultado.pValor;
const n = resultado.n;
const gl = Number.isFinite(resultado.gl) ? resultado.gl : (n - 2);
const esSpearman = this._esSpearman(resultado.tipoCorrelacion);
const tipoCoef = esSpearman ? 'ρ' : 'r';
const tipoRelacion = esSpearman ? 'monotónica' : 'lineal';
const fuerza = (resultado.interpretacion && resultado.interpretacion.fuerza) || 'indeterminada';
const direccion = (resultado.interpretacion && resultado.interpretacion.direccion) || (coef >= 0 ? 'positiva' : 'negativa');
const coefAbs = Math.abs(coef);
const r2 = Number.isFinite(resultado.r2) ? resultado.r2 : coef * coef;
const ic = resultado.intervaloConfianza || null;
const poder = Number.isFinite(resultado.poder) ? resultado.poder : null;
let texto = '';
// 1) Método aplicado (corregido: reconoce 'Spearman (Rho)')
if (esSpearman) {
texto += `Dado que al menos una de las variables incumplió el supuesto de normalidad, se calculó el coeficiente de correlación de Spearman (ρ), que evalúa la relación monotónica entre ${var1} y ${var2} a partir de sus rangos. `;
} else {
texto += `Dado que ambas variables cumplieron el supuesto de normalidad, se calculó el coeficiente de correlación de Pearson (r), que evalúa la relación lineal entre ${var1} y ${var2}. `;
}
// 2) Reporte del resultado (estilo APA, con IC si está disponible)
texto += `El análisis arrojó ${tipoCoef}(${gl}) = ${this._fmtNum(coef)}, ${this._fmtP(pValor)} (N = ${n})`;
if (ic && Number.isFinite(ic.inferior) && Number.isFinite(ic.superior)) {
const nivelIC = Math.round((ic.nivel || 0.95) * 100);
texto += `, IC ${nivelIC}% [${this._fmtNum(ic.inferior)}, ${this._fmtNum(ic.superior)}]`;
}
texto += `. `;
// 3) Dirección y magnitud
if (coefAbs < 0.1) {
texto += `El coeficiente es prácticamente nulo: no se aprecia una asociación ${tipoRelacion} apreciable entre las variables. `;
} else {
texto += `La magnitud corresponde a una correlación ${fuerza} de dirección ${direccion}. `;
if (direccion === 'positiva') {
texto += `En términos sustantivos, las personas con puntuaciones más altas en ${var1} tienden a presentar también puntuaciones más altas en ${var2} (y viceversa). `;
} else {
texto += `En términos sustantivos, las personas con puntuaciones más altas en ${var1} tienden a presentar puntuaciones más bajas en ${var2}: una relación inversa. `;
}
}
// 4) Significancia estadística
if (pValor < 0.05) {
texto += pValor < 0.01
? `El resultado es estadísticamente significativo incluso bajo el criterio exigente de 0.01 (${this._fmtP(pValor)}), lo que aporta evidencia sólida de que la asociación observada no se debe al azar muestral. `
: `El resultado es estadísticamente significativo al nivel convencional de 0.05 (${this._fmtP(pValor)}), lo que indica que la asociación observada difícilmente se explica por el azar muestral. `;
} else {
texto += `El resultado NO alcanzó significancia estadística (${this._fmtP(pValor)} ≥ 0.05): los datos no aportan evidencia suficiente de una asociación ${tipoRelacion} en la población. `;
texto += `Cabe precisar la lectura correcta de este hallazgo: la ausencia de evidencia de asociación no equivale a evidencia de ausencia de asociación. `;
}
// 5) Tamaño del efecto (Cohen, 1988) y varianza compartida
texto += `En cuanto al tamaño del efecto, |${tipoCoef}| = ${this._fmtNum(coefAbs, 2)} se clasifica como ${this._benchmarkCohen(coefAbs)} según los puntos de corte de Cohen (1988: 0.10 pequeño, 0.30 mediano, 0.50 grande). `;
if (esSpearman) {
texto += `Asimismo, ρ² = ${this._fmtNum(r2, 3)} indica que las variables comparten aproximadamente el ${(r2 * 100).toFixed(1)}% de la varianza de sus RANGOS (al ser un índice basado en rangos, no debe leerse como varianza explicada en sentido lineal estricto). `;
} else {
texto += `Asimismo, el coeficiente de determinación r² = ${this._fmtNum(r2, 3)} indica que ${var1} y ${var2} comparten aproximadamente el ${(r2 * 100).toFixed(1)}% de su varianza; el ${(100 - r2 * 100).toFixed(1)}% restante obedece a otros factores no contemplados en este análisis bivariado. `;
}
// 6) Intervalo de confianza: precisión y coherencia con la decisión
if (ic && Number.isFinite(ic.inferior) && Number.isFinite(ic.superior)) {
const cruzaCero = ic.inferior <= 0 && ic.superior >= 0;
if (cruzaCero) {
texto += `El intervalo de confianza incluye el valor cero, lo que es coherente con la falta de significancia: no puede descartarse que la correlación poblacional sea nula. `;
} else {
texto += `El intervalo de confianza excluye el cero, de modo que incluso el escenario más conservador del intervalo sigue indicando una asociación ${direccion} en la población. `;
}
}
// 7) Potencia post-hoc, especialmente informativa cuando no hay significancia
if (poder !== null) {
if (pValor >= 0.05 && poder < 0.8) {
texto += `No puede descartarse un error de Tipo II: con este tamaño muestral, un efecto real de esta magnitud podría haber pasado inadvertido.`;
} else if (pValor >= 0.05) {
texto += `El tamaño muestral otorgaba capacidad razonable para detectar el efecto si existiera; la no significancia resulta, por tanto, informativa.`;
} else {
texto += `La precisión del intervalo de confianza respalda la estabilidad del hallazgo.`;
}
}
return texto;
},
// ========================================
// INTERPRETACIONES DE PRUEBA DE HIPÓTESIS
// ========================================
generarInterpretacionHipotesis(var1, var2, resultado, prueba) {
const coef = resultado.coeficiente;
const pValor = resultado.pValor;
const alpha = prueba.alpha;
const n = resultado.n;
const gl = Number.isFinite(resultado.gl) ? resultado.gl : (n - 2);
const esSpearman = this._esSpearman(resultado.tipoCorrelacion);
// Distinción muestral/poblacional: r y ρ estiman el parámetro poblacional
const simboloPob = esSpearman ? 'ρₛ' : 'ρ';
const simboloMuestral = esSpearman ? 'ρ' : 'r';
const esBilateral = resultado.tipoPrueba !== 'unilateral';
const coefAbs = Math.abs(coef);
const poder = Number.isFinite(resultado.poder) ? resultado.poder : null;
let texto = '';
// 1) Planteamiento formal
texto += `En el marco de la prueba de hipótesis se contrastó H₀: ${simboloPob} = 0 (la correlación poblacional entre ${var1} y ${var2} es nula) `;
texto += esBilateral
? `frente a H₁: ${simboloPob} ≠ 0 (existe correlación, en cualquier dirección), mediante una prueba bilateral `
: `frente a H₁ direccional (${simboloPob} ${coef >= 0 ? '>' : '<'} 0), mediante una prueba unilateral `;
texto += `con un nivel de significancia α = ${alpha}. `;
texto += `La regla de decisión fue: rechazar H₀ si p < α. `;
// 2) Evidencia y decisión
texto += `Con ${simboloMuestral}(${gl}) = ${this._fmtNum(coef)} y ${this._fmtP(pValor)}, `;
if (prueba.decision === 'rechazar') {
texto += `el p-valor resulta inferior al nivel de significancia (${this._fmtP(pValor)}, frente a α = ${alpha}), por lo que SE RECHAZA H₀. `;
texto += `Se concluye que existe evidencia estadísticamente suficiente para afirmar que la correlación entre ${var1} y ${var2} en la población es distinta de cero. `;
// Salvaguardas profesionales
texto += `Dos precisiones son obligadas en un reporte riguroso. Primera: significancia estadística no equivale a relevancia práctica; la importancia del hallazgo debe juzgarse por el tamaño del efecto (|${simboloMuestral}| = ${this._fmtNum(coefAbs, 2)}) y no por el p-valor. `;
texto += `Segunda: correlación no implica causalidad; este resultado documenta covariación sistemática, pero la dirección causal solo podría establecerse con un diseño experimental o longitudinal apropiado. `;
} else {
texto += `el p-valor no es inferior al nivel de significancia (${this._fmtP(pValor)}, frente a α = ${alpha}), por lo que NO SE RECHAZA H₀. `;
texto += `Se concluye que no existe evidencia suficiente para afirmar que la correlación poblacional entre ${var1} y ${var2} sea distinta de cero. `;
texto += `Conviene subrayar que esta decisión NO equivale a "aceptar" H₀: la prueba no demuestra que la correlación sea exactamente nula, solo que los datos no permiten descartarlo. `;
if (coefAbs < 0.1) {
texto += `De hecho, el coeficiente observado es prácticamente nulo, lo que sugiere ausencia de relación apreciable también en el plano descriptivo. `;
} else {
texto += `No obstante, el coeficiente observado (${simboloMuestral} = ${this._fmtNum(coef)}) describe una tendencia que la variabilidad muestral no permite generalizar; `;
texto += poder !== null && poder < 0.8
? `un estudio con mayor tamaño muestral podría esclarecer si esta tendencia constituye un efecto real (posible error de Tipo II). `
: `un estudio de replicación permitiría esclarecer si esta tendencia constituye un efecto real. `;
}
}
// 3) Recomendaciones metodológicas según el tamaño muestral
texto += `Para futuras investigaciones se recomienda `;
if (n < 30) {
texto += `aumentar el tamaño muestral (N actual = ${n}): por debajo de 30 casos el poder estadístico es reducido y las estimaciones del coeficiente resultan inestables. `;
} else if (n < 100) {
texto += `incrementar el tamaño muestral (N actual = ${n}) para ganar precisión en la estimación del parámetro poblacional y estrechar el intervalo de confianza. `;
} else if (n < 200) {
texto += `mantener o ampliar el tamaño muestral (N = ${n}), ya adecuado para análisis bivariados, si se planea escalar hacia modelos multivariados más exigentes. `;
} else {
texto += `aprovechar el tamaño muestral disponible (N = ${n}), que ofrece un poder estadístico excelente, para análisis más avanzados; con muestras grandes conviene además recordar que efectos diminutos pueden resultar significativos, por lo que el tamaño del efecto debe guiar la interpretación. `;
}
// 4) Líneas de profundización
texto += esSpearman
? `Asimismo, se sugiere explorar posibles variables mediadoras o moderadoras, considerar transformaciones o métodos robustos si se desea modelar la relación, y triangular estos hallazgos cuantitativos con evidencia cualitativa para una comprensión más completa del fenómeno (Hernández-Sampieri y Mendoza, 2023).`
: `Asimismo, se sugiere complementar con un análisis de regresión lineal (viable al cumplirse la normalidad), explorar posibles variables mediadoras o moderadoras, y triangular estos hallazgos cuantitativos con evidencia cualitativa para una comprensión más completa del fenómeno (Hernández-Sampieri y Mendoza, 2023).`;
return texto;
},
// ========================================
// MARCO METODOLÓGICO (prosa de investigación)
// Movido desde el analizador: el analizador CALCULA, este módulo REDACTA.
// Reciben todo por parámetro (sin estado), para poder usarse desde
// cualquier parte y probarse de forma aislada.
// ========================================
generarPreguntaInvestigacion(var1, var2, unidadAnalisis, lugarContexto) {
if (!unidadAnalisis || !lugarContexto) {
return `¿Cuál es la relación entre ${var1} ${this._conj(var2)} ${var2}?`;
}
return `¿Cuál es la relación entre ${var1} ${this._conj(var2)} ${var2} en ${unidadAnalisis} de ${lugarContexto}?`;
},
generarObjetivoGeneral(var1, var2, unidadAnalisis, lugarContexto) {
if (!unidadAnalisis || !lugarContexto) {
return `Determinar la relación entre ${var1} ${this._conj(var2)} ${var2}.`;
}
return `Determinar la relación entre ${var1} ${this._conj(var2)} ${var2} en ${unidadAnalisis} de ${lugarContexto}.`;
},
// dimensiones1/dimensiones2: objetos {nombreDimension: ...} o arreglos de
// nombres, o null. opciones (opcional): { unidadAnalisis, lugarContexto,
// sociodemograficos: ['Sexo', 'Grado académico', ...] }.
// Redacción profesional: verbos académicos rotativos (taxonomía de objetivos),
// correlacionales (dimensión ↔ variable general, en ambas direcciones) y
// comparativos según variables sociodemográficas.
_VERBOS_CORRELACIONALES: ['Identificar', 'Establecer', 'Precisar', 'Determinar', 'Indicar', 'Examinar'],
_nombresDe(dimensiones) {
if (!dimensiones) return [];
return Array.isArray(dimensiones) ? dimensiones.slice() : Object.keys(dimensiones);
},
generarObjetivosEspecificos(var1, var2, dimensiones1, dimensiones2, opciones = {}) {
const dims1 = this._nombresDe(dimensiones1);
const dims2 = this._nombresDe(dimensiones2);
const contexto = (opciones.unidadAnalisis && opciones.lugarContexto)
? ` en ${opciones.unidadAnalisis} de ${opciones.lugarContexto}`
: '';
const objetivos = [];
let v = 0;
const verbo = () => this._VERBOS_CORRELACIONALES[(v++) % this._VERBOS_CORRELACIONALES.length];
// 1) Correlacionales: cada dimensión de una variable con la OTRA variable
// (estructura estándar de tesis: dimensión → constructo general).
dims1.forEach(d => {
objetivos.push(`${verbo()} la relación entre la dimensión ${d} de ${var1} ${this._conj(var2)} ${var2}${contexto}.`);
});
dims2.forEach(d => {
objetivos.push(`${verbo()} la relación entre la dimensión ${d} de ${var2} ${this._conj(var1)} ${var1}${contexto}.`);
});
if (dims1.length === 0 && dims2.length === 0) {
objetivos.push(`Establecer el vínculo entre ${var1} ${this._conj(var2)} ${var2}${contexto}.`);
}
// 2) Comparativos: diferencias según variables sociodemográficas.
objetivos.push(...this._objetivosComparativos(var1, var2, opciones.sociodemograficos || [],
opciones.unidadAnalisis, opciones.lugarContexto));
return objetivos;
},
_objetivosComparativos(var1, var2, sociodemograficos, unidadAnalisis, lugarContexto) {
const contexto = (unidadAnalisis && lugarContexto)
? ` en ${unidadAnalisis} de ${lugarContexto}`
: '';
return (sociodemograficos || []).filter(s => !!s).map((s, i) => {
const verboComp = i % 2 === 0 ? 'Analizar las diferencias' : 'Comparar los niveles';
return `${verboComp} de ${var1} ${this._conj(var2)} ${var2} según ${s.toLowerCase()}${contexto}.`;
});
},
// Redacta el objetivo específico de UN par seleccionado por la criba.
// sel: {etiquetaX, etiquetaY, pruebaDeX, pruebaDeY?, tipoPar}; i: índice (rota el verbo).
generarObjetivoDeParSeleccionado(sel, i, contexto) {
const verbo = this._VERBOS_CORRELACIONALES[i % this._VERBOS_CORRELACIONALES.length];
const deX = sel.pruebaDeX ? ` de ${sel.pruebaDeX}` : '';
if (sel.tipoPar === 'dim-dim') {
const deY = sel.pruebaDeY ? ` de ${sel.pruebaDeY}` : '';
return `${verbo} la relación entre la dimensión ${sel.etiquetaX}${deX} y la dimensión ${sel.etiquetaY}${deY}${contexto || ''}.`;
}
return `${verbo} la relación entre la dimensión ${sel.etiquetaX}${deX} ${this._conj(sel.etiquetaY)} ${sel.etiquetaY}${contexto || ''}.`;
},
// Lista completa de objetivos desde la selección de la criba (mismo orden).
generarObjetivosDesdeSeleccion(seleccionados, opciones = {}) {
const contexto = (opciones.unidadAnalisis && opciones.lugarContexto)
? ` en ${opciones.unidadAnalisis} de ${opciones.lugarContexto}`
: '';
return (seleccionados || []).map((sel, i) => this.generarObjetivoDeParSeleccionado(sel, i, contexto));
},
// Hipótesis específicas derivadas de los objetivos específicos (para la
// matriz de consistencia y, después, el Word). Transformación lingüística:
// correlacionales → "Existe una relación..."; comparativos → "Existen diferencias...".
generarHipotesisEspecificas(objetivos) {
return (objetivos || []).map(o => o
.replace(/^(Identificar|Establecer|Precisar|Determinar|Indicar|Examinar)\s+(la relación|el vínculo)( existente)? entre\s*/i,
'Existe una relación estadísticamente significativa entre ')
.replace(/^(Analizar las diferencias|Comparar los niveles)\s+de\s*/i,
'Existen diferencias estadísticamente significativas en '));
},
// Resumen profesional del proceso de criba (selección de objetivos por datos).
// criba: salida de CribaCorrelaciones.cribar.
generarResumenCriba(criba) {
const validos = criba.evaluados.filter(e => e.valido);
const sel = criba.seleccionados;
if (validos.length === 0 || sel.length === 0) {
return `Se evaluaron ${validos.length} pares candidatos y no fue posible seleccionar objetivos (datos insuficientes o no numéricos).`;
}
const selSobreUmbral = sel.filter(s => s.superaUmbral).length;
let t = `Se evaluaron ${validos.length} pares candidatos y se seleccionaron los ${sel.length} de mayor magnitud absoluta, priorizando los pares dimensión ↔ escala general: `;
t += sel.map(s => `${s.etiquetaX} ↔ ${s.etiquetaY} (${this._esSpearman(s.metodo) ? 'ρ' : 'r'} = ${s.coeficiente.toFixed(3)})`).join('; ') + '. ';
if (selSobreUmbral === sel.length) {
t += `Todos alcanzan el criterio de Cohen (1988) de |r| ≥ ${criba.umbral.toFixed(2)} para un efecto al menos pequeño. `;
} else {
t += `${selSobreUmbral} de ${sel.length} alcanzan el criterio de Cohen (1988) de |r| ≥ ${criba.umbral.toFixed(2)}; los restantes deben interpretarse como asociaciones muy débiles, probablemente sin relevancia práctica. `;
}
t += `El signo indica la dirección (positiva = directa; negativa = inversa); la selección compara por magnitud absoluta, de modo que las relaciones inversas compiten en igualdad de condiciones.`;
return t;
},
// Resumen profesional del análisis por dimensiones: cuántos objetivos
// específicos correlacionales se confirmaron, rango de coeficientes y
// dimensión con la asociación más fuerte.
// filas: [{ etiquetaDimension, coeficiente, pValor, significativa, fuerza, tipoCorrelacion }]
generarResumenDimensiones(etiquetaObjetivo, filas) {
if (!filas || filas.length === 0) return '';
const sig = filas.filter(f => f.significativa);
const abs = filas.map(f => Math.abs(f.coeficiente));
const minC = Math.min(...abs), maxC = Math.max(...abs);
const masFuerte = filas.reduce((a, b) => Math.abs(b.coeficiente) > Math.abs(a.coeficiente) ? b : a);
let t = `En síntesis, de las ${filas.length} dimensiones analizadas en relación con ${etiquetaObjetivo}, `;
if (sig.length === filas.length) {
t += `TODAS presentaron una correlación estadísticamente significativa, `;
} else if (sig.length === 0) {
t += `NINGUNA alcanzó significancia estadística, `;
} else {
t += `${sig.length} presentaron una correlación estadísticamente significativa y ${filas.length - sig.length} no, `;
}
t += `con coeficientes cuya magnitud absoluta osciló entre ${minC.toFixed(3)} y ${maxC.toFixed(3)}. `;
t += `La asociación más fuerte correspondió a la dimensión ${masFuerte.etiquetaDimension} `;
t += `(${this._esSpearman(masFuerte.tipoCorrelacion) ? 'ρ' : 'r'} = ${masFuerte.coeficiente.toFixed(3)}, ${this._fmtP(masFuerte.pValor)}, magnitud ${masFuerte.fuerza}). `;
if (sig.length > 0 && sig.length < filas.length) {
t += `Este patrón diferencial es informativo en sí mismo: sugiere que la relación con ${etiquetaObjetivo} no es homogénea entre los componentes del constructo, lo que conviene retomar en la discusión. `;
}
t += `Cada resultado responde a su objetivo específico correspondiente y debe reportarse con su tabla y su interpretación individual.`;
return t;
},
generarHipotesis(var1, var2, unidadAnalisis, lugarContexto) {
let contexto = '';
if (unidadAnalisis && lugarContexto) {
contexto = ` en ${unidadAnalisis} de ${lugarContexto}`;
}
return {
hipotesisInvestigador: `Existe una relación estadísticamente significativa entre ${var1} ${this._conj(var2)} ${var2}${contexto}.`,
hipotesisNula: `No existe una relación estadísticamente significativa entre ${var1} ${this._conj(var2)} ${var2}${contexto}.`,
hipotesisAlterna: `Sí existe una relación estadísticamente significativa entre ${var1} ${this._conj(var2)} ${var2}${contexto}.`
};
},
// TIPO Y DISEÑO DE ESTUDIO (redacción profesional para tesis).
// Personalizable: variables (etiquetas humanas), contexto (unidad/lugar),
// instrumentos detectados de la estructura de pruebas y tamaño muestral.
// Citas: Arias (2021), Hernández-Sampieri y Mendoza (2023),
// Cvetković-Vega et al. (2021) — todas dentro de la ventana de 5 años.
generarTipoYDiseno(var1, var2, opciones = {}) {
const u = opciones.unidadAnalisis, l = opciones.lugarContexto;
const contexto = (u && l) ? ` en ${u} de ${l}` : (u ? ` en ${u}` : '');
const conj = this._conj(var2);
const i1 = opciones.instrumento1, i2 = opciones.instrumento2;
const p1 = `Según su finalidad, la presente investigación es de tipo básica, dado que su propósito es ampliar el conocimiento teórico sobre la relación entre ${var1} ${conj} ${var2}${contexto}, sin perseguir una aplicación inmediata de los resultados: su aporte consiste en consolidar la evidencia empírica disponible sobre el vínculo entre ambos constructos (Arias, 2021).`;
let frInstr;
if (i1 && i2 && i1 !== i2) {
frInstr = `, operacionalizadas en este estudio mediante ${i1} para la medición de ${var1} y ${i2} para ${var2}`;
} else if (i1 || i2) {
frInstr = `, operacionalizadas mediante ${i1 || i2} y los instrumentos estandarizados correspondientes`;
} else {
frInstr = `, operacionalizadas mediante instrumentos estandarizados de medición psicológica`;
}
const p2 = `El enfoque es cuantitativo, pues la aproximación al fenómeno se realiza a través de la medición numérica de las variables${frInstr}, y del análisis de los datos con procedimientos estadísticos descriptivos e inferenciales que permiten contrastar las hipótesis planteadas (Hernández-Sampieri y Mendoza, 2023).`;
const p3 = `El diseño es no experimental, en tanto las variables no fueron manipuladas ni controladas deliberadamente: se observaron y midieron tal como se manifiestan en su contexto natural, sin intervención del investigador (Hernández-Sampieri y Mendoza, 2023). Asimismo, el alcance es correlacional, ya que el objetivo central consiste en determinar el grado de asociación entre ${var1} ${conj} ${var2} mediante estadística inferencial, documentando la covariación entre los constructos sin pretender, por la propia naturaleza del diseño, el establecimiento de relaciones de causa y efecto (Arias, 2021).`;
const frN = opciones.n ? ` de los ${opciones.n} participantes` : '';
const p4 = `Finalmente, según su temporalidad, corresponde a un estudio de corte transversal, porque los datos${frN} se recolectaron en un único momento: ello permite obtener una caracterización del fenómeno y estimar la asociación entre las variables en ese punto del tiempo, sin requerir un seguimiento longitudinal de la muestra (Cvetković-Vega et al., 2021).`;
return [p1, p2, p3, p4].join('\n\n');
},
// opciones: { dimensiones1, dimensiones2, configuracion }
generarMarcoMetodologico(var1, var2, unidadAnalisis, lugarContexto, opciones = {}) {
return {
preguntaInvestigacion: this.generarPreguntaInvestigacion(var1, var2, unidadAnalisis, lugarContexto),
objetivoGeneral: this.generarObjetivoGeneral(var1, var2, unidadAnalisis, lugarContexto),
objetivosEspecificos: opciones.objetivosPersonalizados
? opciones.objetivosPersonalizados.concat(this._objetivosComparativos(
var1, var2, opciones.sociodemograficos || [], unidadAnalisis, lugarContexto))
: this.generarObjetivosEspecificos(
var1, var2,
opciones.dimensiones1 || null,
opciones.dimensiones2 || null,
{ unidadAnalisis, lugarContexto, sociodemograficos: opciones.sociodemograficos || [] }
),
hipotesis: this.generarHipotesis(var1, var2, unidadAnalisis, lugarContexto),
tipoYDiseno: this.generarTipoYDiseno(var1, var2, {
unidadAnalisis, lugarContexto,
instrumento1: opciones.instrumento1 || null,
instrumento2: opciones.instrumento2 || null,
n: opciones.n || null
}),
configuracion: opciones.configuracion || null
};
},
// ========================================
// DISCUSIÓN PROFESIONAL (plantilla para tesis)
// resultado: salida de calcularCorrelacion; pruebaHip: salida de pruebaHipotesis.
// ========================================
generarDiscusion(var1, var2, resultado, pruebaHip, unidadAnalisis, lugarContexto, opciones = {}) {
// Si el llamador ya construyó el marco (p. ej. con dimensiones reales y
// objetivos comparativos), se reutiliza para mantener UNA sola versión.
const marco = opciones.marco || this.generarMarcoMetodologico(var1, var2, unidadAnalisis, lugarContexto, opciones);
const esSpearman = this._esSpearman(resultado.tipoCorrelacion);
const nombreMetodo = esSpearman ? 'Spearman (ρ)' : 'Pearson (r)';
const simbolo = esSpearman ? 'ρ' : 'r';
const gl = Number.isFinite(resultado.gl) ? resultado.gl : (resultado.n - 2);
const coefAbs = Math.abs(resultado.coeficiente);
const r2 = Number.isFinite(resultado.r2) ? resultado.r2 : resultado.coeficiente * resultado.coeficiente;
const ic = resultado.intervaloConfianza || null;
const poder = Number.isFinite(resultado.poder) ? resultado.poder : null;
const n1 = resultado.normalidad1, n2 = resultado.normalidad2;
const simNorm = norm => (norm.prueba && norm.prueba.includes('Shapiro')) ? 'W' : 'D';
let contexto = '';
if (unidadAnalisis && lugarContexto) {
contexto = ` en ${unidadAnalisis} de ${lugarContexto}`;
}
let d = '';
// Sección 1: Marco de la investigación
d += `**MARCO DE INVESTIGACIÓN**\n\n`;
d += `**Pregunta de Investigación:**\n${marco.preguntaInvestigacion}\n\n`;
d += `**Objetivo General:**\n${marco.objetivoGeneral}\n\n`;
if (marco.objetivosEspecificos.length > 0) {
d += `**Objetivos Específicos:**\n`;
marco.objetivosEspecificos.forEach((obj, idx) => { d += `${idx + 1}. ${obj}\n`; });
d += '\n';
}
d += `**Hipótesis de Investigación:**\n${marco.hipotesis.hipotesisInvestigador}\n\n`;
d += `**Hipótesis Nula (H₀):**\n${marco.hipotesis.hipotesisNula}\n\n`;
d += `**Hipótesis Alterna (H₁):**\n${marco.hipotesis.hipotesisAlterna}\n\n`;
// Sección 2: Metodología
d += `---\n\n**METODOLOGÍA ESTADÍSTICA**\n\n`;
d += `El análisis correlacional se realizó mediante el coeficiente de ${nombreMetodo}, seleccionado a partir de las pruebas de normalidad. `;
if (n1.normal && n2.normal) {
d += `Ambas variables cumplieron el supuesto de normalidad (${var1}: ${simNorm(n1)} = ${this._fmtNum(n1.estadistico)}, ${this._fmtP(n1.pValor)}; ${var2}: ${simNorm(n2)} = ${this._fmtNum(n2.estadistico)}, ${this._fmtP(n2.pValor)}; criterio p > 0.05), lo que habilita la estadística paramétrica y el análisis de la relación LINEAL entre las variables. Cabe señalar que el coeficiente de Pearson asume, además, linealidad de la relación y es sensible a valores atípicos; el diagrama de dispersión —con su recta de regresión y banda de confianza al 95%— permite verificar visualmente ambos supuestos.\n\n`;
} else {
d += `Al menos una variable se desvió significativamente de la normalidad (${var1}: ${this._fmtP(n1.pValor)}; ${var2}: ${this._fmtP(n2.pValor)}; criterio p > 0.05), por lo que se optó por el método no paramétrico basado en rangos, que evalúa la relación MONOTÓNICA entre las variables.\n\n`;
}
d += `Se estableció un nivel de significancia de α = ${pruebaHip.alpha}, mediante una prueba ${resultado.tipoPrueba === 'unilateral' ? 'unilateral' : 'bilateral'}.\n\n`;
// Sección 3: Resultados
d += `---\n\n**RESULTADOS**\n\n`;
d += `El análisis arrojó ${simbolo}(${gl}) = ${this._fmtNum(resultado.coeficiente)}, ${this._fmtP(resultado.pValor)} (N = ${resultado.n})`;
if (ic && Number.isFinite(ic.inferior) && Number.isFinite(ic.superior)) {
d += `, IC ${Math.round((ic.nivel || 0.95) * 100)}% [${this._fmtNum(ic.inferior)}, ${this._fmtNum(ic.superior)}]`;
}
d += `. `;
if (pruebaHip.decision === 'rechazar') {
d += `Dado que el p-valor es inferior a α (${this._fmtP(resultado.pValor)} frente a α = ${pruebaHip.alpha}), se rechaza la hipótesis nula: **existe una relación estadísticamente significativa** entre ${var1} y ${var2}${contexto}.\n\n`;
d += `La magnitud corresponde a una correlación **${resultado.interpretacion.fuerza}** de dirección **${resultado.interpretacion.direccion}** (tamaño del efecto ${this._benchmarkCohen(coefAbs)} según Cohen, 1988), lo que indica que ${resultado.interpretacion.direccion === 'positiva'
? 'a medida que aumenta una variable, la otra tiende a aumentar'
: 'a medida que aumenta una variable, la otra tiende a disminuir'}. `;
d += esSpearman
? `El coeficiente al cuadrado (ρ² = ${this._fmtNum(r2)}) indica que las variables comparten aproximadamente el ${(r2 * 100).toFixed(1)}% de la varianza de sus rangos.\n\n`
: `El coeficiente de determinación (r² = ${this._fmtNum(r2)}) indica que las variables comparten aproximadamente el ${(r2 * 100).toFixed(1)}% de su varianza.\n\n`;
} else {
d += `Dado que el p-valor no es inferior a α (${this._fmtP(resultado.pValor)} frente a α = ${pruebaHip.alpha}), no se rechaza la hipótesis nula: **no existe evidencia suficiente** de una relación estadísticamente significativa entre ${var1} y ${var2}${contexto}. `;
d += `Cabe recordar que no rechazar H₀ no equivale a demostrar que la correlación poblacional sea nula`;
d += (poder !== null && poder < 0.8)
? `; no puede descartarse un error de Tipo II.\n\n`
: `.\n\n`;
}
// Sección 4: Interpretación y Discusión (plantilla con espacios para el marco teórico)
d += `---\n\n**DISCUSIÓN E INTERPRETACIÓN**\n\n`;
if (pruebaHip.decision === 'rechazar') {
d += `Los hallazgos confirman la hipótesis de investigación planteada. `;
d += `Este resultado puede interpretarse en el contexto de [MARCO TEÓRICO]. `;
d += `Según [AUTOR] ([AÑO]), [CONCEPTO TEÓRICO RELACIONADO].\n\n`;
d += `La relación ${resultado.interpretacion.direccion} observada sugiere que [INTERPRETACIÓN TEÓRICA]. `;
d += `Esto coincide con lo reportado por [AUTOR] ([AÑO]), quien encontró [HALLAZGO SIMILAR]. `;
d += `Conviene recordar que, al tratarse de un diseño correlacional, la covariación documentada no permite establecer relaciones de causalidad.\n\n`;
} else {
d += `La ausencia de una relación estadísticamente significativa puede explicarse por diversos factores, incluyendo [POSIBLES EXPLICACIONES]. `;
d += `Este resultado contrasta con [AUTOR] ([AÑO]), quien reportó [HALLAZGO DIFERENTE]. `;
d += `Las diferencias metodológicas, contextuales o muestrales podrían explicar esta discrepancia.\n\n`;
}
d += `**Implicaciones:**\n- [IMPLICACIÓN TEÓRICA]\n- [IMPLICACIÓN PRÁCTICA]\n- [IMPLICACIÓN METODOLÓGICA]\n\n`;
d += `**Limitaciones del estudio:**\n- [LIMITACIÓN MUESTRAL/METODOLÓGICA]\n- [LIMITACIÓN DE GENERALIZACIÓN]\n- El diseño correlacional de corte transversal no permite inferencias causales.\n\n`;
d += `**Recomendaciones para futuras investigaciones:**\n- [RECOMENDACIÓN 1]\n- [RECOMENDACIÓN 2]\n`;
return d;
},
// ========================================
// COMPARACIÓN DE GRUPOS (movido desde app.js)
// resultado: salida de la comparación (descriptivas1/2, etiquetas, prueba,
// tamanoEfecto, decision).
// ========================================
generarInterpretacionComparacion(varCuantitativa, varAgrupacion, resultado) {
const significativa = resultado.decision === 'rechazar';
const d1 = resultado.descriptivas1;
const d2 = resultado.descriptivas2;
const grupoMayor = d1.media >= d2.media ? resultado.etiqueta1 : resultado.etiqueta2;
const prueba = resultado.prueba;
const ef = resultado.tamanoEfecto;
const pTexto = this._fmtP(prueba.pValor);
// Tamaño del efecto: r de rangos si la prueba fue no paramétrica
// (apropiado para Mann-Whitney); d de Cohen en el caso paramétrico.
const efTexto = resultado.tamanoEfectoRangos
? `r de rangos = ${resultado.tamanoEfectoRangos.r.toFixed(2)}, tamaño ${resultado.tamanoEfectoRangos.interpretacion}`
: `d de Cohen = ${ef.d.toFixed(2)}, tamaño ${ef.interpretacion}`;
if (significativa) {
return `Existe una diferencia estadísticamente significativa en ${varCuantitativa} entre los grupos de ${varAgrupacion} (${prueba.prueba}, ${pTexto}). El grupo "${grupoMayor}" presenta la media más alta. La magnitud de la diferencia corresponde a ${efTexto}. Una diferencia significativa no implica causalidad cuando los grupos no se asignaron al azar.`;
}
return `No se hallaron diferencias estadísticamente significativas en ${varCuantitativa} entre los grupos de ${varAgrupacion} (${prueba.prueba}, ${pTexto}); el tamaño del efecto corresponde a ${efTexto}. Un resultado no significativo no demuestra la igualdad de los grupos: podría deberse a un tamaño muestral insuficiente para detectar la diferencia.`;
}
};
// Exportar para uso global
if (typeof window !== 'undefined') {
window.InterpretacionesEstadisticas = InterpretacionesEstadisticas;
}