web-dev-qa-db-fra.com

Remplacez NA dans la colonne par la valeur dans la colonne adjacente

Cette question est liée à un article avec un titre similaire ( remplacer NA dans un vecteur R avec des valeurs adjacentes ). Je voudrais scanner une colonne dans un bloc de données et remplacer les NA par la valeur dans la cellule adjacente. Dans l'article susmentionné, la solution consistait à remplacer l'AN non par la valeur du vecteur adjacent (par exemple, l'élément adjacent dans la matrice de données) mais était un remplacement conditionnel pour une valeur fixe. Voici un exemple reproductible de mon problème:

UNIT <- c(NA,NA, 200, 200, 200, 200, 200, 300, 300, 300,300)
STATUS <-c('ACTIVE','INACTIVE','ACTIVE','ACTIVE','INACTIVE','ACTIVE','INACTIVE','ACTIVE','ACTIVE',
                    'ACTIVE','INACTIVE') 
TERMINATED <- c('1999-07-06' , '2008-12-05' , '2000-08-18' , '2000-08-18' ,'2000-08-18' ,'2008-08-18',
                        '2008-08-18','2006-09-19','2006-09-19' ,'2006-09-19' ,'1999-03-15') 
START <- c('2007-04-23','2008-12-06','2004-06-01','2007-02-01','2008-04-19','2010-11-29','2010-12-30',
                   '2007-10-29','2008-02-05','2008-06-30','2009-02-07')
STOP <- c('2008-12-05','4712-12-31','2007-01-31','2008-04-18','2010-11-28','2010-12-29','4712-12-31',
                  '2008-02-04','2008-06-29','2009-02-06','4712-12-31')
#creating dataframe
TEST <- data.frame(UNIT,STATUS,TERMINATED,START,STOP); TEST                   

  UNIT   STATUS TERMINATED      START       STOP
1    NA   ACTIVE 1999-07-06 2007-04-23 2008-12-05
2    NA INACTIVE 2008-12-05 2008-12-06 4712-12-31
3   200   ACTIVE 2000-08-18 2004-06-01 2007-01-31
4   200   ACTIVE 2000-08-18 2007-02-01 2008-04-18
5   200 INACTIVE 2000-08-18 2008-04-19 2010-11-28
6   200   ACTIVE 2008-08-18 2010-11-29 2010-12-29
7   200 INACTIVE 2008-08-18 2010-12-30 4712-12-31
8   300   ACTIVE 2006-09-19 2007-10-29 2008-02-04
9   300   ACTIVE 2006-09-19 2008-02-05 2008-06-29
10  300   ACTIVE 2006-09-19 2008-06-30 2009-02-06
11  300 INACTIVE 1999-03-15 2009-02-07 4712-12-31

#using the syntax for a conditional replace and hoping it works :/          
TEST$UNIT[is.na(TEST$UNIT)] <- TEST$STATUS; TEST 

   UNIT   STATUS TERMINATED      START       STOP
1     1   ACTIVE 1999-07-06 2007-04-23 2008-12-05
2     2 INACTIVE 2008-12-05 2008-12-06 4712-12-31
3   200   ACTIVE 2000-08-18 2004-06-01 2007-01-31
4   200   ACTIVE 2000-08-18 2007-02-01 2008-04-18
5   200 INACTIVE 2000-08-18 2008-04-19 2010-11-28
6   200   ACTIVE 2008-08-18 2010-11-29 2010-12-29
7   200 INACTIVE 2008-08-18 2010-12-30 4712-12-31
8   300   ACTIVE 2006-09-19 2007-10-29 2008-02-04
9   300   ACTIVE 2006-09-19 2008-02-05 2008-06-29
10  300   ACTIVE 2006-09-19 2008-06-30 2009-02-06
11  300 INACTIVE 1999-03-15 2009-02-07 4712-12-31

Le résultat devrait être:

      UNIT   STATUS TERMINATED      START       STOP
1   ACTIVE   ACTIVE 1999-07-06 2007-04-23 2008-12-05
2 INACTIVE INACTIVE 2008-12-05 2008-12-06 4712-12-31
3      200   ACTIVE 2000-08-18 2004-06-01 2007-01-31
4      200   ACTIVE 2000-08-18 2007-02-01 2008-04-18
5      200 INACTIVE 2000-08-18 2008-04-19 2010-11-28
6      200   ACTIVE 2008-08-18 2010-11-29 2010-12-29
7      200 INACTIVE 2008-08-18 2010-12-30 4712-12-31
8      300   ACTIVE 2006-09-19 2007-10-29 2008-02-04
9      300   ACTIVE 2006-09-19 2008-02-05 2008-06-29
10     300   ACTIVE 2006-09-19 2008-06-30 2009-02-06
11     300 INACTIVE 1999-03-15 2009-02-07 4712-12-31
24
hubert_farnsworth

Cela n'a pas fonctionné parce que le statut était un facteur. Lorsque vous mélangez le facteur avec le numérique, le numérique est le moins restrictif. En forçant le statut à être un caractère, vous obtenez les résultats que vous recherchez et la colonne est maintenant un vecteur de caractères:

TEST$UNIT[is.na(TEST$UNIT)] <- as.character(TEST$STATUS[is.na(TEST$UNIT)])

##        UNIT   STATUS TERMINATED      START       STOP
## 1    ACTIVE   ACTIVE 1999-07-06 2007-04-23 2008-12-05
## 2  INACTIVE INACTIVE 2008-12-05 2008-12-06 4712-12-31
## 3       200   ACTIVE 2000-08-18 2004-06-01 2007-01-31
## 4       200   ACTIVE 2000-08-18 2007-02-01 2008-04-18
## 5       200 INACTIVE 2000-08-18 2008-04-19 2010-11-28
## 6       200   ACTIVE 2008-08-18 2010-11-29 2010-12-29
## 7       200 INACTIVE 2008-08-18 2010-12-30 4712-12-31
## 8       300   ACTIVE 2006-09-19 2007-10-29 2008-02-04
## 9       300   ACTIVE 2006-09-19 2008-02-05 2008-06-29
## 10      300   ACTIVE 2006-09-19 2008-06-30 2009-02-06
## 11      300 INACTIVE 1999-03-15 2009-02-07 4712-12-31
30
Tyler Rinker

Tu dois faire

TEST$UNIT[is.na(TEST$UNIT)] <- TEST$STATUS[is.na(TEST$UNIT)]

de sorte que la valeur sera remplacée par la valeur adjacente. Sinon, il existe un décalage entre le nombre de valeurs à remplacer et les valeurs avec lesquelles les remplacer. Cela entraînerait le remplacement des valeurs dans l'ordre des lignes. Cela fonctionne dans ce cas car les deux valeurs remplacées sont les deux premières.

13
Brennan
TEST$UNIT = ifelse(is.na(TEST$UNIT), paste(TEST$STATUS),paste(TEST$UNIT));TEST
       UNIT   STATUS TERMINATED      START       STOP
1    ACTIVE   ACTIVE 1999-07-06 2007-04-23 2008-12-05
2  INACTIVE INACTIVE 2008-12-05 2008-12-06 4712-12-31
3       200   ACTIVE 2000-08-18 2004-06-01 2007-01-31
4       200   ACTIVE 2000-08-18 2007-02-01 2008-04-18
5       200 INACTIVE 2000-08-18 2008-04-19 2010-11-28
6       200   ACTIVE 2008-08-18 2010-11-29 2010-12-29
7       200 INACTIVE 2008-08-18 2010-12-30 4712-12-31
8       300   ACTIVE 2006-09-19 2007-10-29 2008-02-04
9       300   ACTIVE 2006-09-19 2008-02-05 2008-06-29
10      300   ACTIVE 2006-09-19 2008-06-30 2009-02-06
11      300 INACTIVE 1999-03-15 2009-02-07 4712-12-31
0
Partson