2015-02-21 12 views
12

Se il mio frame di dati (df) si presenta così:aggiornare un valore in una colonna Sulla base di criteri in Altre colonne

Name  State 
John Smith MI 
John Smith WI 
Jeff Smith WI 

voglio rinominare la John Smith da WI "John smith1". Qual è l'equivalente R più pulito dell'istruzione SQL?

update df 
set Name = "John Smith1" 
where Name = "John Smith" 
and State = "WI" 
+1

Forse così? 'df [df $ Nome ==" John_Smith "& df $ Stato ==" WI ", 1] <-" John_Smith1 "' – DatamineR

+0

RStudent è on, nel caso in cui la prima colonna non sia di classe 'factor' –

+0

funziona quasi, ma ho una grande quantità di dati, quindi ho cercato di semplificare la domanda. La tua soluzione aggiunge "John_Smith1" alla prima colonna del mio frame di dati, non alla colonna df $ Name. –

risposta

14
df <- data.frame(Name=c('John Smith', 'John Smith', 'Jeff Smith'), 
       State=c('MI','WI','WI'), stringsAsFactors=F) 

df <- within(df, Name[Name == 'John Smith' & State == 'WI'] <- 'John Smith1') 

> df 
     Name State 
1 John Smith MI 
2 John Smith1 WI 
3 Jeff Smith WI 
5

Un modo:

df[df$Name == "John_Smith" & df$State == "WI", "Name"] <- "John_Smith1" 

Un altro modo con il dplyr:

df %>% mutate(Name = ifelse(State == "WI" & Name == "John_Smith", "John_Smith1", Name)) 

Nota: Come dice David Arenburg, la prima colonna non dovrebbe essere un fattore. Per questo, leggendo il set di dati stringsAsFactors = FALSE.

2

È inoltre possibile utilizzare il pacchetto data.table:

library(data.table) 
setDT(df)[State=="WI", Name:=paste0(Name,"1")] 
+0

Questo codice rinominerà anche 'Jeff Smith' in' Jeff Smith1'. Usa 'setDT (df) [Stato ==" WI "& Nome ==" John Smith ", Nome: = pasta0 (Nome," 1 ")]' per rinominare solo 'John Smith' da' WI'. – Uwe

0

Come il PO ha mentioned che ha "una grande cornice di dati", potrebbe essere utile usare una ricerca binaria

library(data.table) 
setDT(DF)[.("John Smith", "WI"), on = .(Name=V1, State=V2), 
      Name := paste0(Name, 1)][] 
  Name State 
1: John Smith MI 
2: John Smith1 WI 
3: Jeff Smith WI 

invece di un vettore scansione

setDT(df)[State == "WI" & Name == "John Smith", Name := paste0(Name, "1")] 

In entrambe le varianti dell'oggetto vengono aggiornati dati per riferimento, cioè, senza copiare l'intero oggetto di risparmiare tempo e memoria.

Problemi correlati