2016-04-28 11 views
6

Sto provando a modificare un data.frame filtrato da dplyr ma non riesco a capire cosa devo fare. Nell'esempio seguente, sto provando a filtrare il frame dati z e poi a assegnare un nuovo valore alla terza colonna: ne fornisco due esempi, uno con "9" e uno con "NA".Come assegnare un valore a un data.frame filtrato da dplyr?

require(dplyr) 
z <- data.frame(w = c("a", "a", "a", "b", "c"), x = 1:5, y = c("a", "b", "c", "d", "e")) 
z %>% filter(w == "a" & x == 2) %>% select(y) 
z %>% filter(w == "a" & x == 2) %>% select(y) <- 9 # Should be similar to z[z$w == "a" & z$ x == 2, 3] <- 9 
z %>% filter(w == "a" & x == 3) %>% select(y) <- NA # Should be similar to z[z$w == "a" & z$ x == 3, 3] <- NA 

Eppure, non funziona: ricevo il seguente messaggio di errore:

"Errore nella z%>% filtro (w == "a" & x == 3)% >% select (y) < - NA: impossibile de trouver la fonction "%>% < -"

so che posso usare la vecchia notazione data.frame, ma quale sarebbe la soluzione per dplyr?

Grazie!

+0

Il tuo 'y' è una colonna di caratteri. Che cosa stai facendo assegnando '9' ad esso? – Frank

risposta

7

Il filtro sostituirà il frame di dati. Se si desidera mantenere l'intero frame dei dati, ma modificarne una parte, è possibile, ad esempio, utilizzare mutate con ifelse. Ho aggiunto stringsAsFactors=FALSE ai dati di esempio in modo che y sia una colonna di caratteri.

z <- data.frame(w = c("a", "a", "a", "b", "c"), x = 1:5, y = c("a", "b", "c", "d", "e"), 
       stringsAsFactors=FALSE) 

z %>% mutate(y = ifelse(w=="a" & x==2, 9, y)) 
w x y 
1 a 1 a 
2 a 2 9 
3 a 3 c 
4 b 4 d 
5 c 5 e 

O con replace:

z %>% mutate(y = replace(y, w=="a" & x==2, 9), 
      y = replace(y, w=="a" & x==3, NA)) 
w x y 
1 a 1 a 
2 a 2 9 
3 a 3 <NA> 
4 b 4 d 
5 c 5 e 
+2

'replace' è un'opzione simile che si incastra bene:' z%>% mutate (y = y%>% replace (w == "a" & x == 2, 9)%>% replace (w == " a "& x == 3, NA))" – Frank

+1

Ci stavo proprio lavorando, ma mi hai battuto per farlo! – eipi10

+0

Si salveranno alcuni caratteri concatenando invece di scrivere più argomenti 'mutate' (basta scrivere' y' due volte, intendo, come nel mio commento), sebbene significhi costruire tubi all'interno dei tubi. – Frank

6

La mia impressione è che il pacchetto dplyr è filosoficamente contrario di modificare i dati sottostanti. Si potrebbe trovare il pacchetto data.table più amichevole per questa operazione:

library(data.table) 
z <- data.table(w = c("a", "a", "a", "b", "c"), x = 1:5, y = c("a", "b", "c", "d", "e")) 
m <- data.table(w = c("a","a"), x = c(2,3), new_y = c("9", NA)) 

z[m, y := new_y, on=c("w","x")] 


    w x y 
1: a 1 a 
2: a 2 9 
3: a 3 NA 
4: b 4 d 
5: c 5 e 

Sono sicuro che c'è un modo di base di R pure, ma io non lo conosco. In particolare, non riesco a ottenere merge o match per fare il lavoro.

+0

Grazie! Questo è un approccio molto creativo alla notazione di i [j] (credo). Grazie per data.table: come molte cose in R, sembra così intuitivo quando gli altri lo fanno, eppure così poco quando uno deve capirlo ... E sì, sono d'accordo con il tuo commento sulla filosofia di dplyr. – nullepart

+0

@ user5 Sì, mi piace molto come la notazione di 'X [Y]' per unire due dati.tables imita la notazione 'X [Y]' per l'inserimento di due matrici nella base R. Io uso questo 'X [Y, v: = new_v] '" Unisci-assegna "la sintassi tutto il tempo. Se sei interessato, le vignette introduttive sono molto chiare: https://github.com/Rdatatable/data.table/wiki/Getting-started – Frank

Problemi correlati