Flujo del experimento: condiciones, saltos, exclusiones y contrabalanceo
Asigna participantes a condiciones entre sujetos, salta páginas o excluye participantes mediante reglas, contrabalancea el orden de las páginas con un cuadrado latino y exporta cada asignación.
Nuevo en v2.12.0
Potato 2.12 añade cinco ajustes para la parte de diseño de un experimento. Cada uno ocupa unas pocas líneas de YAML, y todo lo que se asignó o mostró a un participante queda registrado, de modo que las exportaciones CSV y TSV pueden escribirlo en participants.csv.
| Ajuste | Qué hace |
|---|---|
conditions | Asigna a cada participante una celda de un diseño entre sujetos |
show_when en una página de fase | Salta la página salvo que se cumpla una regla |
exit_when en una página de fase | Termina el estudio para el participante, como hace un cuestionario de selección |
phases.counterbalance | Ordena un grupo de páginas para cada participante, al azar o por cuadrado latino |
randomize_questions en una página de encuesta | Ordena las preguntas de esa página para cada participante |
Las páginas sobre las que actúan estos ajustes son las páginas de fase descritas en Flujos de trabajo multifase: consent, prestudy, instructions, training, annotation y poststudy, además de las páginas de ejecución que ejecutan una línea de tiempo de jsPsych, una comprobación de auriculares o una tarea externa.
Condiciones
conditions:
factors:
feedback: [none, immediate]
font: [serif, sans]
assignment: balanced # balanced | random | round_robin
balance_on: assigned # assigned | completed
max_per_cell: 40 # optionalDos factores con dos niveles cada uno dan cuatro celdas. A un participante se le asigna una celda la primera vez que el servidor lo ve, y la conserva tras recargar la página o reiniciar el servidor.
| Clave | Valor predeterminado | Significado |
|---|---|---|
factors | obligatorio | Nombre del factor asociado a una lista de al menos dos niveles |
assignment | balanced | balanced elige la celda con menos participantes y deshace los empates al azar para cada participante. random sortea una celda, con una semilla por participante. round_robin recorre las celdas en orden de llegada |
balance_on | assigned | completed cuenta solo a los participantes que llegaron al final sin ser excluidos, de modo que un abandono lo reemplaza la siguiente persona que llega |
max_per_cell | ninguno | Una celda llena se omite. Cuando todas las celdas están llenas, se usa la menos ocupada y se registra una advertencia |
cells | factorial completo | Una lista explícita de celdas, un subconjunto del factorial, cada una con un weight opcional |
Las celdas con peso dan a una condición una proporción mayor de participantes:
conditions:
factors:
prime: [none, positive, negative]
cells:
- {prime: none, weight: 2}
- {prime: positive}
- {prime: negative}Pon entre comillas los nombres de nivel que YAML lee como booleanos ("yes", "no", "on", "off"). Tanto el validador como el servidor informan de uno sin comillas como error.
Comprobar una condición en las reglas
Las reglas se refieren a un factor como condition.<factor> en el show_when de una página, el exit_when de una página y el display_logic de una pregunta. El valor que se compara con un factor tiene que ser uno de sus niveles, porque de lo contrario una errata ocultaría la página o la pregunta a todo el mundo, y el validador informa de cualquier valor que no lo sea.
- name: feedback_rating
annotation_type: likert
description: How useful was the feedback?
size: 5
display_logic:
show_when:
- {schema: condition.feedback, operator: equals, value: immediate}Una pregunta oculta por su condición no es obligatoria, ni en la página ni en el servidor.
Ítems distintos para cada celda
Para dar a cada celda sus propios ítems, nombra los grupos de lotes según los niveles de un factor. Así es como un diseño de listas en cuadrado latino asigna una lista a cada participante:
conditions:
factors:
list: [list_a, list_b]
assignment_strategy: batch
batch_assignment:
auto_assign_annotators: true
group_by_condition: list
groups:
- {name: list_a, data_file: data/list_a.jsonl}
- {name: list_b, data_file: data/list_b.jsonl}Los ID de los ítems deben ser únicos en todos los archivos de datos, incluidos los archivos de grupos distintos. El servidor no arranca cuando dos listas comparten un ID, así que un estímulo que aparece en ambas listas necesita un ID distinto en cada una, como h1_a y h1_b.
Una línea de tiempo de jsPsych recibe las condiciones del participante como potato.conditions, y sus datos de ensayo obtienen una columna condition_<factor> por cada factor. Consulta Fases de ejecución.
Redacción según la condición
{condition.<factor>} en cualquier lugar de una página, en el texto de un ítem, la redacción de una pregunta o las etiquetas de las opciones, se sustituye por el nivel de ese factor que tiene el participante. Un experimento de respaldo o una viñeta factorial varía su texto de esta manera:
conditions:
factors:
endorser: ["The city council", "A neighbourhood association"]{"id": "p1", "text": "{condition.endorser} proposes turning the car park into a park."}La sustitución se escapa como HTML. Un marcador de posición para un factor en el que el participante no tiene nivel se queda en la página tal como está escrito, de modo que una errata aparece durante las pruebas. Un elemento con data-condition-only="factor=level" se elimina para todos los que no están en ese nivel, que es como un experimento de lista muestra la afirmación sensible solo al grupo de tratamiento.
Las exportaciones escriben el texto del ítem tal como está en el archivo de datos, con el marcador de posición. Los desplazamientos de los fragmentos cuentan los caracteres del texto ya rellenado, tal como lo vio el participante, así que un fragmento situado después de un marcador de posición no coincide con el texto exportado. Desplázalo según la diferencia de longitud entre el marcador de posición y el nivel del participante (sus condiciones están en la exportación), o bien mantén los marcadores de posición fuera del texto que se anota con fragmentos.
Saltar páginas con show_when
phases:
order: [screener, smoking_followup, general, annotation]
screener:
type: prestudy
file: surveys/screener.json
smoking_followup:
type: prestudy
file: surveys/smoking.json
show_when:
- {schema: smoker, operator: equals, value: "Yes"}
general:
type: prestudy
file: surveys/general.jsonLa gramática es la misma que usan las preguntas condicionales a nivel de pregunta: una lista de condiciones con schema, operator y value, combinadas con logic: all (el valor predeterminado) o logic: any, con los mismos 19 operadores y grupos anidados all, any y not. Una regla puede comprobar cualquier pregunta formulada en una página anterior, en cualquier fase, y cualquier condition.<factor>.
La regla se comprueba cuando el participante sale de la página anterior. Una página oculta se omite en ambas direcciones: Next la salta y Previous no se detiene en ella. Cada salto queda registrado.
El servidor se niega a arrancar con una regla que nombra una pregunta que ninguna página formula, o una que se formula en la misma página o en una posterior, ya que esa pregunta solo podría estar sin responder. La fase de anotación en sí no se puede saltar.
Excluir participantes con exit_when
phases:
screener:
type: prestudy
file: surveys/screener.json
exit_when:
show_when:
- {schema: age, operator: lt, value: 18}
message: This study is for adults only. Thank you for your time.La regla se comprueba cuando el participante envía la página, así que puede comprobar preguntas de esa misma página. Cuando se cumple, el participante pasa al final del estudio:
- Sin un proveedor de crowdsourcing, ve
message. - Con uno (Prolific, SONA, CloudResearch Connect y los demás), recibe el resultado de exclusión de la plataforma y nunca el código de finalización.
exit_when funciona en las páginas consent, prestudy, instructions y poststudy. Un participante excluido se queda al final del estudio. Previous no lo lleva de vuelta, ni siquiera con allow_phase_back_navigation, y el servidor no guarda nada más de lo que envíe. Las respuestas que dio antes de la exclusión permanecen en user_state.json, y la exclusión se escribe en participants.csv, no en annotations.csv.
Orden de páginas contrabalanceado
phases:
order: [intro, block_a, block_b, block_c, annotation]
# ...block definitions...
counterbalance:
- pages: [block_a, block_b, block_c]
method: latin_square # or randomLas páginas conservan las posiciones que ocupan en order, y cada participante recibe su propia disposición de ellas.
randomsortea una permutación con una semilla basada en el participante, así que es la misma tras recargar o reiniciar.latin_squaretoma filas de un cuadrado latino balanceado (de Williams) en orden de llegada. Conconditionsconfigurado, el orden de llegada se cuenta dentro de cada celda, de modo que cada condición recorre el cuadrado completo y el orden de las páginas queda balanceado dentro de cada condición en lugar de confundirse con ella. Con un número impar de páginas, el cuadrado tiene el doble de filas. Los contadores se reconstruyen a partir de los estados guardados cuando el servidor se reinicia.
Todas las páginas de un grupo deben tener el mismo tipo de fase. Las páginas de tipos distintos nunca están una junto a otra en un estudio, así que no podrían intercambiar sus posiciones.
Orden de las preguntas en una página de encuesta
phases:
big_five:
type: poststudy
instrument: tipi
randomize_questions:
pin_last: [comments] # or: randomize_questions: trueCada participante ve las preguntas de la página en su propio orden, con una semilla basada en el participante y la página, y registrado la primera vez que se muestra la página. pin_first y pin_last mantienen las preguntas indicadas en uno u otro extremo. Las páginas organizadas con layout.groups conservan su orden. El orden de las opciones dentro de una pregunta es un ajuste aparte, randomize_order en el esquema.
El registro del flujo
user_state.json guarda un flow_record para cada participante:
| Clave | Contenido |
|---|---|
conditions, condition_cell, condition_ordinal | La celda asignada y el número de llegada en todo el estudio |
cell_ordinal | Número de llegada dentro de la celda, que elige la fila del cuadrado latino cuando hay condiciones configuradas |
latin_ordinal | Número de llegada para las filas del cuadrado latino cuando no hay condiciones configuradas |
page_orders | El orden de cada grupo contrabalanceado |
question_orders | El orden de las preguntas de cada página aleatorizada |
skipped_pages | Páginas omitidas por show_when |
screened_out | La página y la hora de una exclusión |
runtimes | Tipo, estado, intentos, cargas de página, número de ensayos e ID de ejecución de cada página de ejecución |
runtime_answers | Lo que las páginas de ejecución derivaron de sus ejecuciones, como el <page>_passed de una comprobación de auriculares |
Las exportaciones CSV y TSV escriben una fila por participante en participants.csv (o .tsv). Con un factor feedback, su cabecera es:
user_id,condition_feedback,condition_ordinal,cell_ordinal,latin_ordinal,final_phase,screened_out,screened_out_page,skipped_pages,page_orders,question_orders,runtime_runs,runtime_answersskipped_pages se separa con |, y las últimas cuatro columnas contienen JSON. El backend de almacenamiento MySQL no guarda el registro del flujo, y un servidor que lo usa registra una advertencia cuando estas funciones están configuradas.
Ejemplo
examples/advanced/jspsych-stroop/ en el repositorio de Potato usa conditions, exit_when, una página de jsPsych y randomize_questions. Arráncalo desde la raíz del repositorio:
python potato/flask_server.py start examples/advanced/jspsych-stroop/config.yaml -p 8000Lecturas adicionales
- Fases de ejecución - Líneas de tiempo de jsPsych, comprobaciones de auriculares y tareas externas como páginas de un estudio
- Ensayos cronometrados - Fijación, duración del estímulo, plazos y tiempos de reacción en los ítems de anotación
- Flujos de trabajo multifase - Consentimiento, cuestionarios de selección, instrucciones, entrenamiento y encuestas
- Si vienes de jsPsych - Conceptos de jsPsych asociados a claves de configuración de Potato
- Experimentos conductuales en línea - Cómo llevar a cabo un estudio de psicología o lingüística en Potato de principio a fin
Para detalles de implementación, consulta la documentación fuente.