Remplacer plusieurs valeurs dans la colonne de la table de données après plusieurs correspondances de modèle

Nov 22 2020

Voici un extrait de code qui pourrait aider quelques `` débutants en R '' comme moi: je faisais référence à ce fil pour un besoin sur ma table de données fondue :

Remplacez la chaîne entière n'importe où dans le dataframe en fonction d'une correspondance partielle avec dplyr

Je cherchais un moyen simple de remplacer une chaîne entière dans l'une des colonnes de la table de données par une chaîne de correspondance partielle. Je n'ai pas pu trouver d'ajustement direct sur le forum, d'où ce post.

dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3")
> dt
      x    y    z
1:  A_1  K_1  P_1
2: BB_2 LL_2 QQ_2
3: CC_3 MM_3 RR_3

remplacez plusieurs valeurs dans col ypar plusieurs modèles pour correspondre:

dt[,2]<-str_replace_all(as.matrix(dt[,2]),c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR"))

l'utilisation as.matrix()de la colonne sur exclut l'avertissement lors de l'entrée de la str_replace_all()fonction. Le résultat est:

> dt[,2]<-str_replace_all(as.matrix(dt[,2]),c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR"))
> dt
      x       y    z
1:  A_1 FORMULA  P_1
2: BB_2    RACE QQ_2
3: CC_3     CAR RR_3
>

très peu élégant, mais a fonctionné pour moi, lorsque les données de la colonne sont volumineuses, cela semblait être une solution rapide.

Nécessite library(stringr). Toutes les suggestions d'amélioration sont appréciées.

Modification de ce message en essayant quelque chose comme ci-dessous:

dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3"))            
dt[, nu_col := c(1:3)]
molten.dt<-melt(dt,id.vars = "nu_col", measure.vars = c("x","y","z"))
molten.dt[, one_more := ifelse(grepl("A_.*", value), "HONDA","FERRARI")]

L'erreur que je vois sur la console de Rstudio est:

Error in `:=`(one_more, ifelse(grepl("A_.*", value), "HONDA", "FERRARI")) : 
  Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").

Fonctionne parfaitement bien sur R Terminal

> dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_$
> dt[, nu_col := c(1:3)]
> molten.dt<-melt(dt,id.vars = "nu_col", measure.vars = c("x","y","z"))
> molten.dt
   nu_col variable value
1:      1        x   A_1
2:      2        x  BB_2
3:      3        x  CC_3
4:      1        y   K_1
5:      2        y  LL_2
6:      3        y  MM_3
7:      1        z   P_1
8:      2        z  QQ_2
9:      3        z  RR_3
> molten.dt[, one_more := ifelse(grepl("A_.*", value), "HONDA","FERRARI")]
> molten.dt
   nu_col variable value one_more
1:      1        x   A_1    HONDA
2:      2        x  BB_2  FERRARI
3:      3        x  CC_3  FERRARI
4:      1        y   K_1  FERRARI
5:      2        y  LL_2  FERRARI
6:      3        y  MM_3  FERRARI
7:      1        z   P_1  FERRARI
8:      2        z  QQ_2  FERRARI
9:      3        z  RR_3  FERRARI
>

Réponses

1 Cole Nov 23 2020 at 01:06

data.table a une API différente pour la mise à jour en place. Alors que ce serait déplyr :

tib <- tib %>% mutate(new_col = old_col + 2)

La même chose se fait en place à l'aide de l' :=opérateur:

dt[, new_col := old_col + 2]

Notez donc qu'une fois que nous sommes entre crochets, nous pouvons passer un vecteur à d'autres fonctions. Pour appliquer cela à votre exemple, nous pouvons faire ...

library(data.table)
library(stringr)
dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3"))            

dt[, y := str_replace_all(y,c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR")) ]               

dt

##         x       y      z
##    <char>  <char> <char>
## 1:    A_1 FORMULA    P_1
## 2:   BB_2    RACE   QQ_2
## 3:   CC_3     CAR   RR_3

Notez, puisque str_replace_allattend un vecteur, vous auriez pu le remplacer as.matrix(dt[,2])par dt[[2]]. La différence est que dt[, 2]produit une data.table à une seule colonne; as.matrix(dt[, 2])produit une matrice de colonne unique, alors que dt[[2]]produit un vecteur. Je recommanderais toujours d'utiliser le dt[, new := old + 2]type de syntaxe.