En la gestión de datos, la deduplicación es una tarea clásica. Habitualmente, cuando se habla de "eliminar duplicados", se desea conservar una única fila para cada clave y eliminar las repeticiones. Esto es lo que hace muy bien un PROC SORT con la opción NODUPKEY.
Sin embargo, existe un caso más estricto: eliminar por completo cualquier grupo de datos que presente duplicados. Si un identificador aparece varias veces, se considera que el dato está "contaminado" o es ambiguo, y no se quiere guardar ningún rastro de esos registros. Solo los identificadores realmente únicos (que aparecen una sola vez en la tabla original) deben sobrevivir.
Tomemos el ejemplo de una tabla que contiene un identificador de cliente (ID) y un año (Year). Una observación se define por la combinación ID + Year.
Datos de entrada:
| Obs | ID | Año | Var1 | Estado |
| 1 | 1 | 1999 | 5 | Único (a conservar) |
| 2 | 2 | 2000 | 10 | Duplicado |
| 3 | 2 | 2000 | 8 | Duplicado |
| 4 | 2 | 2000 | 6 | Duplicado |
| 5 | 3 | 2001 | 7 | Único (a conservar) |
| 6 | 4 | 2002 | 12 | Duplicado |
| 7 | 4 | 2002 | 15 | Duplicado |
El objetivo es obtener una tabla que contenga solo las observaciones 1 y 5. Los grupos de ID 2 y 4 deben desaparecer por completo.
Si utiliza PROC SORT NODUPKEY, SAS© conservará la primera fila de cada grupo (la fila 2 y la fila 6 permanecerían), lo cual no es el resultado deseado aquí.
El método más elegante y conciso para realizar esta operación utiliza PROC SQL. La idea es agrupar los datos por la clave de identificación, contar el número de elementos en cada grupo y filtrar solo aquellos cuya cuenta sea estrictamente igual a 1.
El Código:
¿Cómo funciona?
GROUP BY id, year: SAS© agrupa virtualmente las filas que comparten el mismo par ID/Año.
HAVING count(*) = 1: Es la condición de filtrado aplicada después de la agrupación.
Para el ID 1 (Año 1999), la cuenta es 1. -> Conservado.
Para el ID 2 (Año 2000), la cuenta es 3. -> Rechazado (todas las filas del grupo son ignoradas).
Este enfoque es muy eficiente porque evita múltiples pasos de ordenamiento y marcado (flagging) en un paso de datos clásico.
Para los puristas del paso DATA, obtener el mismo resultado requeriría una lógica de "doble lectura" o el uso de las variables automáticas first. y last. después de un ordenamiento, verificando si first.id es igual a last.id (lo que significa que solo hay una fila para ese ID).