Home > front end >  How can I replace multiple strings in a vector using variables and not hard coding the pattern using
How can I replace multiple strings in a vector using variables and not hard coding the pattern using

Time:04-12

I have the following vector and data frame:

v <- c(1:20)
df <- data.frame(CHR=c(1:23), val=sample(100, 23, replace=TRUE))

and I want to create the following vector:

v2 <- c(as.character(v), "X", "Y", "Z")

In my real code the length of the vector and df will differ, so I am trying to create the v2 character vector using str_replace_all like so:

v2 <- str_replace_all(as.character(df$CHR), c(as.character(length(v)   1) = "X", as.character(length(v)   2) = "Y"), as.character(length(v)   3) = "Z"))

However this throws an error "unexpected '=' in "labels <- str_replace_all(as.character(df$CHR), c(as.character(length(v) 1) =""

I thought I was using str_replace_all correctly. If I simply run:

labels <- str_replace_all(as.character(df$CHR), c("21" = "X", "22" = "Y", "23" = "Z"))

I get the correct result but I don't want to hard code.

If my code evaluates to the same string pattern, why doesn't it work? please let me know if you can help.

CodePudding user response:

We may use setNames to create the named vector instead of passing an expression on the lhs of =

library(stringr)
str_replace_all(as.character(df$CHR), 
       setNames(c("X", "Y", "Z"), length(v)   1:3))

-output

[1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "X" 
[22] "Y"  "Z" 

If we want to use expression on the lhs, use := operator

library(dplyr)
dplyr::lst(!!as.character(length(v)   1) := "X", 
    !!as.character(length(v)   2) := "Y", !!as.character(length(v)   3) := "Z")
$`21`
[1] "X"

$`22`
[1] "Y"

$`23`
[1] "Z"

and then use it as

str_replace_all(as.character(df$CHR), 
   unlist(dplyr::lst(!!as.character(length(v)   1) := "X", 
   !!as.character(length(v)   2) := "Y",
   !!as.character(length(v)   3) := "Z")))
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" "20" "X"  "Y"  "Z" 

CodePudding user response:

Update: without hard coding:

v2 <- c(intersect(v, df$CHR), LETTERS[(dim(df)[1] 1):26])

First answer: Maybe this one?

v2 <- c(intersect(v, df$CHR), LETTERS[24:26])
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8" 
 [9] "9"  "10" "11" "12" "13" "14" "15" "16"
[17] "17" "18" "19" "20" "X"  "Y"  "Z"
  • Related