2014-09-18 6 views
5

Ho bisogno di impostare determinati valori numerici in una colonna del mio data frame a zero, se in un'altra colonna hanno un determinato livello di fattore.Modifica valori numerici in una colonna in base ai livelli dei fattori in un'altra colonna

mio dataframe df sembra qualcosa di simile:

Items Store.Type 
5  A 
4  B 
3  C 
6  D 
3  B 
7  E 

Quello che voglio fare è fare oggetti = 0, per tutte le righe in cui Store.Type = "A" o "C"

I' È molto nuovo per R, ma ho pensato che si tratterebbe di un'istruzione condizionale del modulo "Se Store.Type A then Items < - 0" (e quindi di ripetere per Store.Type C), ma non ho capito la pagina ?"if" affatto. Ho provato:

df$ItemsFIXED <- with(df, if(Store.Type == "A")Items <-0) 

e ottenuto il messaggio di avviso:

Warning message: 
In if (Store.Type2 == "Chain - Brand") Total.generic.items <- 0 : 
the condition has length > 1 and only the first element will be used` 

Così ho notato here, il seguente:

  • if is a control flow statement, taking a single logical value as an argument
  • ifelse is a vectorised function, taking vectors as all its arguments.

Così capire che ho bisogno ifelse di fare tutta la colonna e di essere in grado di capire la pagina ?ifelse, ho provato a fare "Se Store.Type A quindi Articoli < - 0 altro non fare nulla". In realtà lo volevo nidificato, così ho provato il seguente codice (la creazione di una nuova colonna per il momento in modo da non rovinare i miei dati, ma alla fine si sovrascrive i dati Items)

df$ItemsFIXED <- with(df, ifelse(Store.Type == "A", Items <-0, 
          ifelse(Store.Type == "C", Items <-0,))) 

ed ha ottenuto la seguente errore:

Error in ifelse(Store.Type2 == "Franchise - Brand", Total.generic.items <- 0, : 
    argument "no" is missing, with no default 

Ma se ho messo nulla in per no semplicemente scrive sopra i valori che sono corretti. Ho provato a inserire Items e Items <- Items in "else leave Items as Items" come di seguito, ma questo ha appena cambiato tutto a zero.

df$ItemsFIXED <- with(df, ifelse(Store.Type == "A", Items <-0, 
          ifelse(Store.Type == "C", Items <-0,Items))) 

C'è un modo per dire ifelse di non fare nulla, o c'è un modo più semplice per fare questo?

+1

'df $ Articoli [che (df $ Store.Type == "A" | df $ Store.Type == "C")] <- 0' – Alex

+0

ie trova le righe che devono essere modificate, quindi imposta queste voci su 0. – Alex

+0

Grazie a tutti per queste soluzioni, funzionano davvero, ma non sono esattamente sicuro di come/perché ancora! Penso che 'which' e'% in% 'sembrano essere i più semplici che dovrei esaminare di più. – JenLouise

risposta

5

Oppure si potrebbe usare %in% per molteplici partita/sostituzione

df$Items[df$Store.Type %in% c("A", "C")] <- 0 
    df 
    #Items Store.Type 
    #1  0   A 
    #2  4   B 
    #3  0   C 
    #4  6   D 
    #5  3   B 
    #6  7   E 
1

Qui è possibile utilizzare la sostituzione vettorializzata. Se df è il set di dati,

> df$Items[with(df, Store.Type == "A" | Store.Type == "C")] <- 0L 
> df 
# Items Store.Type 
# 1  0   A 
# 2  4   B 
# 3  0   C 
# 4  6   D 
# 5  3   B 
# 6  7   E 

with(df, Store.Type == "A" | Store.Type == "C") restituisce un vettore logico. Quando viene inserito un vettore logico all'interno di [...], vengono restituiti solo i valori TRUE. Quindi, se sottoinsieme Items con quei valori, possiamo sostituirli con [<-

Inoltre, se si voleva utilizzare ifelse, si potrebbe fare le cose come

df$Items <- with(df, ifelse(Store.Type == "A" | Store.Type == "C", 0L, Items)) 

o

within(df, Items <- ifelse(Store.Type == "A" | Store.Type == "C", 0L, Items)) 

ma prendere nota che ifelse può essere molto lento, a volte, ancor più quando accoppiato con within, e sarà probabilmente sempre più lento del metodo vettorializzato verso l'alto.

1

seguito anche funziona:

> ddf[ddf$Store.Type=='A'| ddf$Store.Type=='C',]$Items = 0 
> ddf 
    Items Store.Type 
1  0   A 
2  4   B 
3  0   C 
4  6   D 
5  3   B 
6  7   E 
2

Utilizzando within sembra essere anche un'opzione:

within(d, Items[Store.Type %in% c("A","C")]<-0) 

    Items Store.Type 
1  0   A 
2  4   B 
3  0   C 
4  6   D 
5  3   B 
6  7   E 
+0

+1 Sembra buono, mai provato prima. – akrun