tomw
tomw

Reputation: 3160

str_replace_all by position, applied over a vector

I have a data frame where each entry is some number of strings, separated by commas. I want a neat way to replace every element by position.

here's a toy version of the data

 library(tidyverse)

d1 <- tibble(
  r1 = c("lab1",
         "lab2,lab3",
         NA,
         "lab3,lab4"),
  r2 = c(NA,
         "lab1",
         "lab2",
         "lab2,lab3")
  ) 

So every lab element I want replacted by the corresponding rep element.

d1 %>% 
  modify_at(1:2,
        ~ str_replace_all(.,
                          c("lab1", "lab2", "lab3", "lab4"),
                          c("rep1", "rep2", "rep3", "rep4")))

Returns

# A tibble: 4 x 2
         r1        r2
      <chr>     <chr>
1      rep1      <NA>
2 rep2,lab3      lab1
3      <NA>      lab2
4 lab3,rep4 lab2,lab3

so I've only made a single replacement per cell in r1, whereas I need to replace them all.

Upvotes: 4

Views: 988

Answers (3)

h3rm4n
h3rm4n

Reputation: 4187

With the stringi-package:

library(stringi)

patt <- c("lab1", "lab2", "lab3", "lab4")
repl <- c("rep1", "rep2", "rep3", "rep4")

d1[] <- lapply(d1, stri_replace_all_fixed, patt, repl, vectorize_all = FALSE)

The result:

> d1
         r1        r2
1      rep1      <NA>
2 rep2,rep3      rep1
3      <NA>      rep2
4 rep3,rep4 rep2,rep3

Upvotes: 1

missuse
missuse

Reputation: 19726

This should work

  d1 %>% 
      modify_at(1:2,
                ~ stringr::str_replace_all(.,
                                           c("lab1" = "rep1",
                                             "lab2" = "rep2",
                                             "lab3" = "rep3",
                                             "lab4" = "rep4")))

To perform multiple replacements in each element of string, pass a named vector (c(pattern1 = replacement1)) to str_replace_all

Upvotes: 6

eipi10
eipi10

Reputation: 93861

You could use multigsub from the qdap package:

library(qdap)

d1 %>% 
  modify_at(1:2,
            ~ multigsub(c("lab1", "lab2", "lab3", "lab4"),
                        c("rep1", "rep2", "rep3", "rep4"),
                        .))
         r1        r2
1      rep1      <NA>
2 rep2,rep3      rep1
3      <NA>      rep2
4 rep3,rep4 rep2,rep3

If your real use case just requires replacing lab with rep, regardless of the number that follows, you could also do:

map_df(d1, ~ gsub("lab", "rep", .x))

Upvotes: 3

Related Questions