Si mon cadre de données (df) ressemble à ceci:
Name State
John Smith MI
John Smith WI
Jeff Smith WI
Je veux renommer le John Smith de WI "John Smith1". Quel est l'équivalent R le plus propre de l'instruction SQL?
update df
set Name = "John Smith1"
where Name = "John Smith"
and State = "WI"
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
Une manière:
df[df$Name == "John_Smith" & df$State == "WI", "Name"] <- "John_Smith1"
Une autre façon d'utiliser la dplyr
:
df %>% mutate(Name = ifelse(State == "WI" & Name == "John_Smith", "John_Smith1", Name))
Remarque: comme le dit David Arenburg, la première colonne ne devrait pas être un facteur. Pour cela, lisez l'ensemble de données stringsAsFactors = FALSE
.
Vous pouvez également utiliser le package data.table
:
library(data.table)
setDT(df)[State=="WI", Name:=paste0(Name,"1")]
Comme le PO a a mentionné qu'il avait "une très grande trame de données", il pourrait être avantageux d'utiliser une recherche binaire.
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
au lieu d'un balayage vectoriel
setDT(df)[State == "WI" & Name == "John Smith", Name := paste0(Name, "1")]
Dans les deux variantes, l’objet de données est mis à jour par référence, c’est-à-dire sans copier l’objet entier, ce qui économise du temps et de la mémoire.