8

I wish to insert a defined variable into a string in R, where the variable will be inserted in multiple places.

I have seen the sprintf may be of use.

Example of desired input:

a <- "tree"
b <- sprintf("The %s is large but %s is small. %s", a) 

Ideal output would return

"The tree is large but tree is small. tree"

I understand that I can use the function like this:

b <- sprintf("The %s is large but %s is small. %s",a,a,a)

However for my actual work I would require the insert 10+ times, so i'm looking for a cleaner/simpler solution.

Would gsub be a better solution?

My exact question has been answered here however it is for the language Go:

Replace all variables in Sprintf with same variable

1
  • 1
    This gsub('%s' ,a, 'The %s is large but %s is small. %s')? Commented Mar 5, 2018 at 13:00

3 Answers 3

18

Here is an actual sprintf() solution:

a <- "tree"
sprintf("The %1$s is large but %1$s is small. %1$s", a)
[1] "The tree is large but tree is small. tree"

There are more examples in the official sprintf() documentation.

Sign up to request clarification or add additional context in comments.

Comments

4

1) glue We can use glue. No packages are used except glue

glue::glue("The {s} is large but {s} is small. {s}", s = a)
#The tree is large but tree is small. tree

2) syntax The syntax is similar to f-string method in python

a = "tree"
print(f"The {a} is large but {a} is small. {a}")
#The tree is large but tree is small. tree

which is similar to the format method but a more readable

print("The {s} is large but {s} is small. {s}".format(s=a))
#The tree is large but tree is small. tree

2 Comments

I usually try to stick with base R if I don't see a clear advantage of a non-base function. Is there some advantage of using glue over e.g. gsub?
@KenS. It is coming from the tidyverse team. Also, it is something in line with the python f'string i.e. a = "tree"; print(f"The {a} is large but {a} is small. {a}")
3

1) do.call Using do.call the a arguments could be constructed using rep. No packages are used.

a <- "tree"
s <- "The %s is large but %s is small. %s"

k <- length(gregexpr("%s", s)[[1]])
do.call("sprintf", as.list(c(s, rep(a, k))))
## [1] "The tree is large but tree is small. tree"

2) gsub This has already been mentioned in the comments but gsub could be used. Again, no packages are used.

gsub("%s", a, s, fixed = TRUE)
## [1] "The tree is large but tree is small. tree"

3) gsubfn The gsubfn package supports a quasi-perl style string interpolation:

library(gsubfn)

a <- "tree"
s2 <- "The $a is large but $a is small. $a"
fn$c(s2)
## [1] "The tree is large but tree is small. tree"

Also, backticks can be used to enclose entire R expressions which are evaluated and substituted in.

This can be used with any function, not just c leading to very compact code. For example suppose that we want to count the characters in s after substitution. Then it could be done like this:

fn$nchar(s2)
## [1] 38

4) $n format notation In sprintf the notation %n$ refers to the nth argument following fmt:

a <- "tree"
s <- "The %1$s is large but %1$s is small. %1$s"
sprintf(s, a)
## [1] "The tree is large but tree is small. tree"

2 Comments

Both solutions work as required. I decided to use gsub over the package glue. Unless there is a reason to not use gsub?
If you are doing straight character string substitution then (2) seems fine. If you need more control over the formatting of the inserted strings then (1) would give you more control using sprintf's % codes and (3) would give you a lot more using backticks. (3) would also be more compact than any of the others since it can operate on the arguments of arbitrary functions as in the example at the end. fn$ is the preferred way to insert strings into SQL statements when using sqldf and is loaded by sqldf automatically for this purpose.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.