4
votes

L'équivalent de R de string.replace () en python

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?


0 commentaires

6 Réponses :


2
votes

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.


4 commentaires

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!



3
votes

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)


0 commentaires

2
votes

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


1 commentaires

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!



2
votes

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")
)


0 commentaires

0
votes
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.

0 commentaires

1
votes

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


0 commentaires