ETL CAS

Imputar valores faltantes con la función LAG

Este código también está disponible en: Deutsch English
Nivel de dificultad
Principiante
Publicado el :
La función LAG es crucial para los tratamientos secuenciales en un DATA Step, especialmente para la imputación de datos. En un entorno SAS© Viya, si los datos se procesan en memoria distribuida (CAS), es imperativo utilizar la opción SESSREF='casauto' SINGLE=YES en la instrucción DATA. Esta opción garantiza que el procesamiento se realice en un solo hilo en un único nodo CAS, evitando así resultados impredecibles debido a la distribución de los datos que impediría a la función LAG ver la observación anterior de manera fiable. El ejemplo muestra una imputación condicional donde, si el valor actual está faltante, se estima a partir del valor del año anterior (aumentado en un 10%). Si el valor anterior también está faltante, la imputación se basa en el valor del penúltimo año (aumentado en un 20%).
Análisis de datos

Type : CREACIÓN_INTERNA


Los ejemplos utilizan datos generados (datalines) para asegurar la autonomía y la reproducibilidad.

1 Bloque de código
DATA STEP Data
Explicación :
Este ejemplo ilustra una imputación simple. Si las ventas de un año son faltantes, se imputan aumentando las ventas del año anterior en un 5%. La variable `last_ventes` se utiliza para conservar el último valor conocido, lo cual es esencial si la imputación basada en `LAG` también encuentra un valor faltante. La opción `single=yes` se especifica para garantizar un procesamiento secuencial en un solo nodo CAS, lo cual es necesario para la función `LAG` en un entorno distribuido.
¡Copiado!
1LIBNAME mycas cas;
2 
3DATA mycas.ventes_annuelles;
4 INPUT Annee Ventes;
5 DATALINES;
6 2020 1000
7 2021 1100
8 2022 .
9 2023 1300
10 2024 .
11 ;
12RUN;
13 
14DATA mycas.ventes_imputees (sessref="casauto" single=yes);
15 SET mycas.ventes_annuelles;
16 retain last_ventes;
17 IF Ventes = . THEN DO;
18 lag_ventes = lag(Ventes);
19 IF lag_ventes ne . THEN Ventes_imputees = lag_ventes * 1.05; /* Imputation avec +5% de l'année précédente */
20 ELSE Ventes_imputees = last_ventes * 1.05; /* Utilise la dernière vente connue si LAG est aussi manquant */
21 END;
22 ELSE DO;
23 Ventes_imputees = Ventes;
24 last_ventes = Ventes;
25 END;
26RUN;
27 
28PROC PRINT DATA=mycas.ventes_imputees;
29 title "Exemple 1: Imputation Basique des Ventes Manquantes";
30RUN;
31 
32PROC CAS;
33 TABLE.dropTable / caslib="mycas" name="ventes_annuelles";
34 TABLE.dropTable / caslib="mycas" name="ventes_imputees";
35RUN;
36 
2 Bloque de código
DATA STEP Data
Explicación :
Este ejemplo avanzado utiliza tanto `LAG` como `LAG2` para gestionar valores faltantes consecutivos. Para cada producto (definido por `BY Produit`), si la cantidad está faltante, el script intenta primero imputarla con la cantidad del mes anterior (aumentada en un 2%). Si la cantidad del mes anterior también está faltante, utiliza la cantidad del penúltimo mes (aumentada en un 4%). Si no hay ningún valor anterior disponible, la cantidad se imputa a 0. La inicialización de las variables `lag_quantite` y `lag2_quantite` en cada nuevo grupo `Produit` es crucial para cálculos correctos.
¡Copiado!
1LIBNAME mycas cas;
2 
3DATA mycas.stock_produit;
4 INPUT Produit $ Mois Quantite;
5 DATALINES;
6 A 1 100
7 A 2 110
8 A 3 .
9 A 4 .
10 A 5 130
11 B 1 200
12 B 2 .
13 B 3 220
14 B 4 230
15 ;
16RUN;
17 
18DATA mycas.stock_impute (sessref="casauto" single=yes);
19 SET mycas.stock_produit;
20 BY Produit;
21 IF first.Produit THEN DO;
22 lag_quantite = .;
23 lag2_quantite = .;
24 END;
25 ELSE DO;
26 lag_quantite = lag(Quantite);
27 lag2_quantite = lag2(Quantite);
28 END;
29 
30 IF Quantite = . THEN DO;
31 IF lag_quantite ne . THEN Quantite_imputee = lag_quantite * 1.02; /* +2% de la valeur précédente */
32 ELSE IF lag2_quantite ne . THEN Quantite_imputee = lag2_quantite * 1.04; /* +4% de la valeur d'avant l'année précédente */
33 ELSE Quantite_imputee = 0; /* Si aucune valeur précédente n'est disponible */
34 END;
35 ELSE Quantite_imputee = Quantite;
36RUN;
37 
38PROC PRINT DATA=mycas.stock_impute;
39 title "Exemple 2: Imputation de Quantités Manquantes avec LAG et LAG2";
40RUN;
41 
42PROC CAS;
43 TABLE.dropTable / caslib="mycas" name="stock_produit";
44 TABLE.dropTable / caslib="mycas" name="stock_impute";
45RUN;
46 
3 Bloque de código
DATA STEP Data
Explicación :
Este ejemplo implementa una imputación avanzada con procesamiento por grupo (`BY Departement Annee`). Para cada departamento y año, los valores faltantes de 'Reclamations' se imputan con el valor del mes anterior. Si el valor anterior también está faltante, se utiliza el último valor no faltante del mismo grupo. `RETAIN` y `FIRST.BYVAR` se usan para gestionar el estado a través de los grupos y reiniciar `LAG` al inicio de cada nuevo grupo. Esto es particularmente útil para datos de panel donde las secuencias deben respetarse por grupo.
¡Copiado!
1LIBNAME mycas cas;
2 
3DATA mycas.reclamations_mensuelles;
4 INPUT Departement $ Annee Mois Reclamations;
5 DATALINES;
6 IT 2022 1 10
7 IT 2022 2 12
8 IT 2022 3 .
9 IT 2022 4 15
10 IT 2023 1 .
11 IT 2023 2 18
12 HR 2022 1 20
13 HR 2022 2 .
14 HR 2022 3 25
15 HR 2023 1 22
16 HR 2023 2 .
17 HR 2023 3 .
18 HR 2023 4 30
19 ;
20RUN;
21 
22DATA mycas.reclamations_imputees (sessref="casauto" single=yes);
23 SET mycas.reclamations_mensuelles;
24 BY Departement Annee;
25 retain last_reclamations_in_group;
26 
27 IF first.Departement or first.Annee THEN DO;
28 lag_reclamations = .;
29 last_reclamations_in_group = .;
30 END;
31 ELSE lag_reclamations = lag(Reclamations);
32 
33 IF Reclamations = . THEN DO;
34 IF lag_reclamations ne . THEN Reclamations_imputees = lag_reclamations;
35 ELSE IF last_reclamations_in_group ne . THEN Reclamations_imputees = last_reclamations_in_group;
36 ELSE Reclamations_imputees = 0; /* Imputation par 0 si aucune valeur précédente */
37 END;
38 ELSE DO;
39 Reclamations_imputees = Reclamations;
40 last_reclamations_in_group = Reclamations;
41 END;
42RUN;
43 
44PROC PRINT DATA=mycas.reclamations_imputees;
45 title "Exemple 3: Imputation de Réclamations Manquantes par Département et Année";
46RUN;
47 
48PROC CAS;
49 TABLE.dropTable / caslib="mycas" name="reclamations_mensuelles";
50 TABLE.dropTable / caslib="mycas" name="reclamations_imputees";
51RUN;
52 
4 Bloque de código
DATA STEP Data
Explicación :
Este ejemplo demuestra la integración en SAS Viya/CAS para la imputación de tiempos de respuesta. Utiliza `SESSREF="casauto" SINGLE=YES` para asegurar que las operaciones `LAG` se realicen correctamente en un solo hilo en el entorno distribuido de CAS. Los valores faltantes se imputan utilizando el último valor conocido dentro de cada `Service`. Si no hay ningún valor anterior disponible (por ejemplo, para la primera observación de un servicio con un valor faltante), se utiliza un valor predeterminado de 30. Este caso resalta la robustez de la lógica de imputación y la gestión de casos límite.
¡Copiado!
1LIBNAME mycas cas;
2 
3DATA mycas.temps_reponse;
4 INPUT Service $ Date : yymmdd. TempsReponse;
5 FORMAT Date yymmdd10.;
6 DATALINES;
7 Email 20230101 15
8 Email 20230102 20
9 Email 20230103 .
10 Email 20230104 .
11 Email 20230105 25
12 Chat 20230101 5
13 Chat 20230102 .
14 Chat 20230103 8
15 ;
16RUN;
17 
18DATA mycas.temps_reponse_impute (sessref="casauto" single=yes);
19 SET mycas.temps_reponse;
20 BY Service;
21 retain last_temps_reponse_service;
22 
23 IF first.Service THEN DO;
24 lag_temps_reponse = .;
25 last_temps_reponse_service = .;
26 END;
27 ELSE lag_temps_reponse = lag(TempsReponse);
28 
29 IF TempsReponse = . THEN DO;
30 IF lag_temps_reponse ne . THEN TempsReponse_impute = lag_temps_reponse;
31 ELSE IF last_temps_reponse_service ne . THEN TempsReponse_impute = last_temps_reponse_service;
32 ELSE TempsReponse_impute = 30; /* Imputation par défaut à 30 si aucune valeur précédente */
33 END;
34 ELSE DO;
35 TempsReponse_impute = TempsReponse;
36 last_temps_reponse_service = TempsReponse;
37 END;
38RUN;
39 
40PROC PRINT DATA=mycas.temps_reponse_impute;
41 title "Exemple 4: Imputation de Temps de Réponse Manquants dans CAS";
42RUN;
43 
44PROC CAS;
45 TABLE.dropTable / caslib="mycas" name="temps_reponse";
46 TABLE.dropTable / caslib="mycas" name="temps_reponse_impute";
47RUN;
48 
Este material se proporciona "tal cual" por We Are Cas. No hay garantías, expresas o implícitas, en cuanto a la comerciabilidad o idoneidad para un propósito particular con respecto a los materiales o el código contenidos en este documento. We Are Cas no es responsable de los errores en este material tal como existe ahora o existirá, ni We Are Cas proporciona soporte técnico para el mismo.
Información de copyright : Copyright © SAS Institute Inc. All Rights Reserved.


Documentación relacionada

Aucune documentation spécifique pour cette catégorie.