2013-03-26 8 views
8

Questa domanda è correlata a un post con un titolo simile (replace NA in an R vector with adjacent values). Mi piacerebbe scansionare una colonna in un frame di dati e sostituire NA con il valore nella cella adiacente. Nel post sopra menzionato, la soluzione consisteva nel sostituire la NA non con il valore del vettore adiacente (ad esempio l'elemento adiacente nella matrice di dati) ma era una sostituzione condizionale per un valore fisso. Di seguito è riportato un esempio riproducibile di mio problema:Sostituisci NA in colonna con valore nella colonna adiacente

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') 

TEST < - data.frame (UNITA ', STATO, 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 

Il risultato dovrebbe essere:

 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

forse prova 'TEST $ UNIT [is.na (TEST $ UNIT)] <- TEST $ STATUS [is.na (TEST $ UNIT)]; TEST ' – Seth

+2

Non è possibile mescolare i tipi all'interno di una colonna in un frame di dati. –

risposta

12

Non ha funzionato perché lo stato era un fattore. Quando si mescola il fattore con il valore numerico, il valore numerico è il meno restrittivo. Forzando lo stato di essere personaggio di ottenere i risultati che stai cercando e la colonna è ora un vettore di carattere:

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 
+0

Più veloce di me di 6 secondi. +1 (sto cancellando il mio). – A5C1D2H2I1M1N2O1R2T1

+2

Per fortuna era il codice e non le pistole :) –

+0

grazie ragazzi! questo ha fatto il trucco –

2

Devi fare

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

in modo che il valore sarà sostituito con il valore adiacente. Altrimenti c'è una discrepanza tra il numero di valori da sostituire e i valori con cui sostituirli. Ciò comporterebbe la sostituzione dei valori nell'ordine delle righe. Funziona in questo caso perché i due valori che vengono sostituiti sono i primi due.

+0

Penso che questo sia OK come risposta. Certo, la soluzione è la stessa di quella data da altri, ma hai aggiunto una spiegazione di cosa sta succedendo. Non dovrebbe essere un commento, secondo me. –