1

I am trying to create a function that can pass two arguments to make up a new concatenated string.

I expect that this function

fun1(apple, orange)

to produce:

apple and orange

However, for some reason, when I run this function, it cant find and pass the arguments.

fun1 <- function(first, second){
  first_str <- as.character(first)
  second_str <- as.character(second) 
  sentence <- str_c(orig_str ," and ", dest_str)
  return(sentence)

Error in fun1(apple, orange) : object 'apple' not found

This would work if I pass a string right away,

fun1("apple", "orange")
[1] apple and orange

My intention is to make users fill the arguments on an input bar, and have the function convert it to the character. Thus I would not want to require the users to use "" and pass arguments in the string format. What would be a good alternative?

  • 1
    In general it is better not to design your functions to accept unevaluated objects `fun1 <- function(first, second) paste(first, "and", second)` is all you need if character strings are passed and then users can also pass variables easily: `fun1("first", "second")` or `v1 <- "first"; v2 <- "second"; fun1(v1, v2)` – G. Grothendieck Jan 23 '21 at 18:19
  • What exactly is an "input bar"? Note that with a set up like this, you'll only be able to accept words that can be interpreted as symbols. You'd never be able to type words that have spaces or hyphens or anything. – MrFlick Jan 23 '21 at 18:32

4 Answers4

0

This will work, but I suspect someone else will come along with a more eloquent answer:

fun1 <- function(first, second){
  first <- enquo(first)
  second <- enquo(second)
  first <- as.character(first)[2]
  second <- as.character(second)[2]
  sentence <- str_c(first ," and ", second)
  return(sentence)
}
fun1(apple, orange)
# [1] "apple and orange"

DaveArmstrong
  • 18,377
  • 2
  • 13
  • 25
0

The solution by Dave works well for a set number of arguments.

An alternative, clunkier option would be to use ellipsis (...) in your function, and then get the names of the provided arguments.

I would not recommend this solution, as it will not work if there are any global variables with the provided name.

Here is an example that would work if you decided to provide strings as input.

fun1 <- function(...) {
args <- list(...)
lappy(args, paste)
}
mhovd
  • 3,724
  • 2
  • 21
  • 47
0

Note that the readline(prompt= "some prompt") function collects user content as character from the terminal. So if you need 2 inputs, you could collect them in 2 readline prompts wrapped by a function:

fun1 <- function(){
  str1 <- readline(prompt="Enter string 1: ")
  str2 <- readline(prompt="Enter string 2: ")
  strs <- paste(str1, "and", str2, sep = " ")
  return(strs)
  
}
SteveM
  • 2,226
  • 3
  • 12
  • 16
0

You might be looking for deparse(substitute)).

fun2 <- function(first, second) {
  paste0(deparse(substitute(first)), " and ", deparse(substitute(second)))
}
fun2(apple, orange)
# [1] "apple and orange"
jay.sf
  • 60,139
  • 8
  • 53
  • 110
  • This works great but for some reason, it automatically adds spaces in between the "and" and the input strings, which makes it rather inflexible. – Joshua Budi Jan 29 '21 at 20:14
  • @JoshuaBudi Use `paste0` instead and put the space into the binding string if needed (edit). – jay.sf Jan 30 '21 at 05:30