2014-10-04 4 views
5

Ho un dataframe esistente molto più grande. Per questo esempio più piccolo vorrei sostituire alcune delle variabili (sostituire lo stato (df1)) con newstate (df2) in base alla colonna "first". Il mio problema è che i valori vengono restituiti come NA poiché solo alcuni nomi sono abbinati nel nuovo dataframe (df2).Hanno un valore di ritorno nomatch poiché utilizza la funzione di corrispondenza in R

dataframe esistente:

state = c("CA","WA","OR","AZ") 
first = c("Jim","Mick","Paul","Ron") 
df1 <- data.frame(first, state) 

     first state 
    1 Jim CA 
    2 Mick WA 
    3 Paul OR 
    4 Ron AZ 

Nuovo dataframe da abbinare a dataframe esistente

state = c("CA","WA") 
newstate = c("TX", "LA") 
first =c("Jim","Mick") 
df2 <- data.frame(first, state, newstate) 

    first state newstate 
1 Jim CA  TX 
2 Mick WA  LA 

provato ad usare partita, ma restituisce NA per "stato" in cui un matching "prima" variabile da DF2 non è trovato nel dataframe originale.

df1$state <- df2$newstate[match(df1$first, df2$first)] 

    first state 
1 Jim TX 
2 Mick LA 
3 Paul <NA> 
4 Ron <NA> 

Esiste un modo per ignorare NoMatch o hanno NoMatch restituire la variabile esistente così com'è? Questo sarebbe un esempio del risultato desiderato: gli stati di Jim/Mick vengono aggiornati mentre lo stato di Paul e Ron non cambiano.

 first state 
    1 Jim TX 
    2 Mick LA 
    3 Paul OR 
    4 Ron AZ 

risposta

6

È questo quello che vuoi; BTW a meno che tu non voglia veramente lavorare con i fattori, usa stringsAsFactors = FALSE nella tua chiamata data.frame. Si noti l'uso di nomatch = 0 nella chiamata di corrispondenza.

> state = c("CA","WA","OR","AZ") 
> first = c("Jim","Mick","Paul","Ron") 
> df1 <- data.frame(first, state, stringsAsFactors = FALSE) 
> state = c("CA","WA") 
> newstate = c("TX", "LA") 
> first =c("Jim","Mick") 
> df2 <- data.frame(first, state, newstate, stringsAsFactors = FALSE) 
> df1 
    first state 
1 Jim CA 
2 Mick WA 
3 Paul OR 
4 Ron AZ 
> df2 
    first state newstate 
1 Jim CA  TX 
2 Mick WA  LA 
> 
> # create an index for the matches 
> indx <- match(df1$first, df2$first, nomatch = 0) 
> df1$state[indx != 0] <- df2$newstate[indx] 
> df1 
    first state 
1 Jim TX 
2 Mick LA 
3 Paul OR 
4 Ron AZ 
+0

Il codice funziona. [Grazie.] Per favore, puoi spiegare perché hai' indx! = 0' sul lato sinistro degli uguali e 'indx' su il lato destro degli uguali? 'df1 $ stato [indx! = 0] <- df2 $ newstate [indx]' –

2
library(data.table) 
DT1 <- as.data.table(df1) 
DT2 <- as.data.table(df2) 


setkey(DT1, first, state) 
setkey(DT2, first, state) 

DT1[DT2] 
# first state newstate 
# 1: Jim CA  TX 
# 2: Mick WA  LA 

noti che [.data.table ha anche un nomatch argomento, vale a dire:

DT2[DT1, nomatch=0] 
# first state newstate 
# 1: Jim CA  TX 
# 2: Mick WA  LA 

DT2[DT1, nomatch=NA] 
# first state newstate 
# 1: Jim CA  TX 
# 2: Mick WA  LA 
# 3: Paul OR  NA 
# 4: Ron AZ  NA 

3

penso si otterrà una migliore comportamento con vettori di carattere che con fattori.

> df1 <- data.frame(first, state,stringsAsFactors=FALSE) 
> state = c("CA","WA") 
> newstate = c("TX", "LA") 
> first =c("Jim","Mick") 
> df2 <- data.frame(first, state, newstate, stringsAsFactors=FALSE) 
> df1[ match(df2$first, df1$first), "state"] <- df2$newstate 
> df1 
    first state 
1 Jim TX 
2 Mick LA 
3 Paul OR 
4 Ron AZ 
+0

Sono riuscito a riprodurre la risposta. Ho quindi convertito i miei dati originali, tutti in caratteri e i formati controllati con str(). Sembrano essere identici nella struttura. Quando provo lo provo sul mio set di dati originale più grande ottengo questo: "Errore in' [<-. Data.frame' ('* tmp *', corrisponde (df2 $ prima, df1 $ prima), : i valori mancanti non sono consentiti nelle assegnazioni di cornici di dati con codice " – panstotts

Problemi correlati