J'ai besoin de remplacer certaines valeurs d'un vecteur de caractères:
x["Strings"].replace(["one", "two", "thre","three"], ["One","Two","Three","Three"], inplace=True)
En python, je ferais:
x <- data.frame(Strings = c("one", "two","three","four","five","four","five","four","five","two","thre","two","three","two","three"), stringsAsFactors = FALSE) > x Strings 1 one 2 two 3 three 4 four 5 five 6 four 7 five 8 four 9 five 10 two 11 three 12 two 13 three 14 two 15 three
Mais en r la fonction replace ()
ne fonctionne pas de la même manière. Il existe de nombreuses solutions pour un remplacement de chaîne dans Stackoverflow, mais personne n'a cette simplicité. Est-ce possible en r?
6 Réponses :
Si vous recherchez la capitalisation, le package Hmisc avec capitalize ()
fonctionnera. Mes excuses si je ne comprends pas bien la question.
library(Hmisc) x <- data.frame(Strings = c("one", "two","three","four","five","four","five","four","five","two","thre","two","three","two","three"), stringsAsFactors = FALSE) x<-sub("thre[^[:space:]]*", "Three", x$Strings) xCap<-capitalize(x) as.data.frame(xCap) xCap 1 One 2 Two 3 Three 4 Four 5 Five 6 Four 7 Five 8 Four 9 Five 10 Two 11 Three 12 Two 13 Three 14 Two 15 Three
Merci à @RuiBarradas dans les commentaires pour le sous-correctif.
Cela ne corrige pas la faute de frappe "Thre"
, comme le souhaite l'OP.
@RuiBarradas je vois, n'a pas lu les données assez attentivement. Je vais clore cette réponse, merci pour la mise en garde.
Ne le fermez pas, modifiez-le. Après votre code, sub ("Thre [^ [: space:]] *", "Three", x $ Strings)
.
J'ai besoin de capitaliser, mais j'ai aussi besoin de remplacer certaines valeurs spécifiques (comme "Thre" dans l'exemple). Alors merci pour votre réponse quand même!
Si tout ce que vous vouliez faire est de mettre en majuscule la première lettre de chaque mot, nous pouvons utiliser sub
:
Strings new 1 one One 2 two Two 3 three Three 4 four four 5 five five 6 four four 7 five five 8 four four 9 five five 10 two Two 11 thre Three 12 two Two 13 three Three 14 two Two 15 three Three
Sortie:
library(dplyr) x$new <- coalesce(replacements[match(x$Strings, pattern)], x$new) library(hashmap) hash_lookup = hashmap(pattern, replacements) x$new <- coalesce(hash_lookup[[x$Strings]], x$new)
S'il existe déjà une liste d'anciens et de nouveaux mots à remplacer, nous pouvons utiliser str_replace_all
, qui a un (genre de) style similaire comme l'exemple de python OP publié:
library(stringr) pattern <- c("one", "two", "thre", "three") replacements <- c("One", "Two", "Three", "Three") named_vec <- setNames(replacements, paste0("\\b", pattern, "\\b")) x$new <- str_replace_all(x$Strings, named_vec)
ou avec match
ou hashmap
:
Strings new 1 one One 2 two Two 3 three Three 4 four Four 5 five Five 6 four Four 7 five Five 8 four Four 9 five Five 10 two Two 11 thre Thre 12 two Two 13 three Three 14 two Two 15 three Three
x$new <- sub('^([a-z])', '\\U\\1', x$Strings, perl = TRUE)
Une solution consiste simplement à les convertir en facteurs , puis à remplacer les niveaux
> x <- data.frame(Strings = c("one", "two","three","four","five","four","five","four","five","two","thre","two","three","two","three"), stringsAsFactors = FALSE) > x$Strings <- as.factor(x$Strings) > levels(x$Strings) <- c("Five", "Four", "One", "Three", "Three", "Two") > x Strings 1 One 2 Two 3 Three 4 Four 5 Five 6 Four 7 Five 8 Four 9 Five 10 Two 11 Three 12 Two 13 Three 14 Two 15 Three
Je suis surpris, cela n'a pas été plus voté. Toute solution simple utilisant uniquement la base R est intrinsèquement meilleure que celle impliquant un package supplémentaire!
Une solution syntaxique proche de votre code Python (utilisant le package plyr
):
x$Strings <- plyr::mapvalues(x$Strings, c("one", "two", "thre","three"), c("One","Two","Three","Three") )
x <- data.frame(Strings = c("one", "two","three","four","five","four","five","four","five","two","thre","two","three","two","three"), stringsAsFactors = FALSE) y=c("one", "two", "thre","three") z=c("One","Two","Three","Three") x$Strings=x%>%rowwise()%>%mutate(Strings=if_else(!is.na(z[match(Strings,y)]), z[match(Strings,y)],false=Strings)) Using dplyr() you would only need to change the y and z.
Voici une option utilisant recode
. Créez une liste de paires clé / valeur, puis utilisez recode
pour faire correspondre les valeurs dans 'Strings' avec la 'clé' de la liste
et remplacez-la par la valeur correspondante
library(tidyverse) lst1 <- list(one = "One", two = "Two", three = "Three", four = "Four", five = "Five") x %>% mutate(Strings = recode(Strings, !!! lst1))
REMARQUE: En supposant que le camelcase soit par hasard