Force argument to have quotes

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Force argument to have quotes

Doran, Harold
I am writing a program where non-technical R users will read in a config file and the config file will then parse the arguments found within the config and pass them to respective functions. I'm having trouble (efficiently) writing a piece of code to retain quotation marks around the argument which requires it as input, as found in the example function below, myFuncton1.

Below is a minimal, reproducible example of the issue with comments.

### This is a sample structure of the configuration file

scoreConfig <- structure(list(Function = c("myFunction1", "myFunction1", "myFunction1",
"myFunction2", "myFunction2"), Argument = c("arg1", "arg2", "arg3",
"arg1", "arg2"), Value = c("5", "10", "Hello", "5", "10"), Class = c("numeric",
"numeric", "character", "numeric", "numeric")), .Names = c("Function",
"Argument", "Value", "Class"), class = "data.frame", row.names = c(NA,
-5L))

### Two sample functions, once of which requires a string
myFunction1 <- function(arg1, arg2, arg3 = c('Hello', 'Goodbye')){
        arg3 <- match.arg(arg3)
        result <- arg1 + arg2
        cat(arg3, result, '\n')
        }
       
       
myFunction2 <- function(arg1, arg2){
        result <- arg1 * arg2
        result
        }


### Working Example.
### myFunction2 works no problem
myFunction2Vals <- subset(scoreConfig, Function == 'myFunction2')
myOptions <- with(myFunction2Vals, paste(Argument, Value, sep = '=', collapse = ','))
eval(parse(text = paste( "myFunction2(", myOptions, ")" )))


### myFunction1 fails
myFunction1Vals <- subset(scoreConfig, Function == 'myFunction1')
myOptions <- with(myFunction1Vals, paste(Argument, Value, sep = '=', collapse = ','))
eval(parse(text = paste( "myFunction1(", myOptions, ")" )))

### What I want is simply
myFunction1(arg1 = 1, arg2 = 2, arg3 = 'Hello')

I'm curious if someone has a perspective on the most efficient way to automate this by using information provided in the 'Value" column, so perhaps conditional on that value it could wrap the name in quotes.

I admit to running into a limit and am tapping out so to speak on the right way to do this.

Thanks for any advice
Harold

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Force argument to have quotes

Boris Steipe
If I understand you correctly what you are really asking is how to embed quotes in a string so that it can be parse()'d as an expression. The answer would be: escape the quotes.


R > myOptions <- "Hello"
R > eval(parse(text = paste( "print(", myOptions, ")" )))
 Error in print(Hello) : object 'Hello' not found

R > eval(parse(text = paste( "print( \"", myOptions, "\")", sep="" )))
[1] "Hello"

(Myself, I would use sprintf(),

R > myFunction <- "print"
R > eval(parse(text = sprintf("%s(\"%s\")", myFunction, myOptions)))
[1] "Hello"

)


Ask again if this is only part of the problem.

B.




> On Jun 6, 2017, at 11:01 AM, Doran, Harold <[hidden email]> wrote:
>
> I am writing a program where non-technical R users will read in a config file and the config file will then parse the arguments found within the config and pass them to respective functions. I'm having trouble (efficiently) writing a piece of code to retain quotation marks around the argument which requires it as input, as found in the example function below, myFuncton1.
>
> Below is a minimal, reproducible example of the issue with comments.
>
> ### This is a sample structure of the configuration file
>
> scoreConfig <- structure(list(Function = c("myFunction1", "myFunction1", "myFunction1",
> "myFunction2", "myFunction2"), Argument = c("arg1", "arg2", "arg3",
> "arg1", "arg2"), Value = c("5", "10", "Hello", "5", "10"), Class = c("numeric",
> "numeric", "character", "numeric", "numeric")), .Names = c("Function",
> "Argument", "Value", "Class"), class = "data.frame", row.names = c(NA,
> -5L))
>
> ### Two sample functions, once of which requires a string
> myFunction1 <- function(arg1, arg2, arg3 = c('Hello', 'Goodbye')){
> arg3 <- match.arg(arg3)
> result <- arg1 + arg2
> cat(arg3, result, '\n')
> }
>
>
> myFunction2 <- function(arg1, arg2){
> result <- arg1 * arg2
> result
> }
>
>
> ### Working Example.
> ### myFunction2 works no problem
> myFunction2Vals <- subset(scoreConfig, Function == 'myFunction2')
> myOptions <- with(myFunction2Vals, paste(Argument, Value, sep = '=', collapse = ','))
> eval(parse(text = paste( "myFunction2(", myOptions, ")" )))
>
>
> ### myFunction1 fails
> myFunction1Vals <- subset(scoreConfig, Function == 'myFunction1')
> myOptions <- with(myFunction1Vals, paste(Argument, Value, sep = '=', collapse = ','))
> eval(parse(text = paste( "myFunction1(", myOptions, ")" )))
>
> ### What I want is simply
> myFunction1(arg1 = 1, arg2 = 2, arg3 = 'Hello')
>
> I'm curious if someone has a perspective on the most efficient way to automate this by using information provided in the 'Value" column, so perhaps conditional on that value it could wrap the name in quotes.
>
> I admit to running into a limit and am tapping out so to speak on the right way to do this.
>
> Thanks for any advice
> Harold
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Force argument to have quotes

Bert Gunter-2
In reply to this post by Doran, Harold
Harold:

As a general rule, if you are using eval(parse(...)) you are doing it
poorly in R; cf

library("fortunes")
fortune(106)

Why is something like this not suitable:

fun1 <- function(a1,a2,a3 = c("hi","by"))
{
   cat(a3,a1+a2,"\n")
}

> fun1 (1,2)
hi by 3
> fun1(1,2, a3 = "whoopee")
whoopee 3

... or, if you want to include the function as an argument of a list:

> myArgs <- list(fun=fun1, arglist=list(a1=2, a2 =5, a3 = c("hi","by")))

For which you can do stuff like:

> do.call(myArgs[[1]],myArgs[-1][[1]])
hi by 7

> arglist <- myArgs[-1][[1]][-3]
> do.call(myArgs[[1]],c(arglist,a3 = "whoopee"))
whoopee 7

etc. etc.
See ?do.call

Cheers,
Bert



Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Tue, Jun 6, 2017 at 8:01 AM, Doran, Harold <[hidden email]> wrote:

> I am writing a program where non-technical R users will read in a config file and the config file will then parse the arguments found within the config and pass them to respective functions. I'm having trouble (efficiently) writing a piece of code to retain quotation marks around the argument which requires it as input, as found in the example function below, myFuncton1.
>
> Below is a minimal, reproducible example of the issue with comments.
>
> ### This is a sample structure of the configuration file
>
> scoreConfig <- structure(list(Function = c("myFunction1", "myFunction1", "myFunction1",
> "myFunction2", "myFunction2"), Argument = c("arg1", "arg2", "arg3",
> "arg1", "arg2"), Value = c("5", "10", "Hello", "5", "10"), Class = c("numeric",
> "numeric", "character", "numeric", "numeric")), .Names = c("Function",
> "Argument", "Value", "Class"), class = "data.frame", row.names = c(NA,
> -5L))
>
> ### Two sample functions, once of which requires a string
> myFunction1 <- function(arg1, arg2, arg3 = c('Hello', 'Goodbye')){
>         arg3 <- match.arg(arg3)
>         result <- arg1 + arg2
>         cat(arg3, result, '\n')
>         }
>
>
> myFunction2 <- function(arg1, arg2){
>         result <- arg1 * arg2
>         result
>         }
>
>
> ### Working Example.
> ### myFunction2 works no problem
> myFunction2Vals <- subset(scoreConfig, Function == 'myFunction2')
> myOptions <- with(myFunction2Vals, paste(Argument, Value, sep = '=', collapse = ','))
> eval(parse(text = paste( "myFunction2(", myOptions, ")" )))
>
>
> ### myFunction1 fails
> myFunction1Vals <- subset(scoreConfig, Function == 'myFunction1')
> myOptions <- with(myFunction1Vals, paste(Argument, Value, sep = '=', collapse = ','))
> eval(parse(text = paste( "myFunction1(", myOptions, ")" )))
>
> ### What I want is simply
> myFunction1(arg1 = 1, arg2 = 2, arg3 = 'Hello')
>
> I'm curious if someone has a perspective on the most efficient way to automate this by using information provided in the 'Value" column, so perhaps conditional on that value it could wrap the name in quotes.
>
> I admit to running into a limit and am tapping out so to speak on the right way to do this.
>
> Thanks for any advice
> Harold
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Force argument to have quotes

Nordlund, Dan (DSHS/RDA)
Bert has suggested there are better ways to do what you want.  But if you want to continue down the path you have started and you want to decide whether to quote based on the variable Class, something like this might work for you  

myOptions <- with(myFunction1Vals, paste(Argument, ifelse(Class=='character',shQuote(Value), Value), sep = '=', collapse = ","))


Hope this helps,

Dan

Daniel Nordlund, PhD
Research and Data Analysis Division
Services & Enterprise Support Administration
Washington State Department of Social and Health Services

> -----Original Message-----
> From: R-help [mailto:[hidden email]] On Behalf Of Bert
> Gunter
> Sent: Tuesday, June 06, 2017 12:14 PM
> To: Doran, Harold
> Cc: [hidden email]
> Subject: Re: [R] Force argument to have quotes
>
> Harold:
>
> As a general rule, if you are using eval(parse(...)) you are doing it
> poorly in R; cf
>
> library("fortunes")
> fortune(106)
>
> Why is something like this not suitable:
>
> fun1 <- function(a1,a2,a3 = c("hi","by"))
> {
>    cat(a3,a1+a2,"\n")
> }
>
> > fun1 (1,2)
> hi by 3
> > fun1(1,2, a3 = "whoopee")
> whoopee 3
>
> ... or, if you want to include the function as an argument of a list:
>
> > myArgs <- list(fun=fun1, arglist=list(a1=2, a2 =5, a3 = c("hi","by")))
>
> For which you can do stuff like:
>
> > do.call(myArgs[[1]],myArgs[-1][[1]])
> hi by 7
>
> > arglist <- myArgs[-1][[1]][-3]
> > do.call(myArgs[[1]],c(arglist,a3 = "whoopee"))
> whoopee 7
>
> etc. etc.
> See ?do.call
>
> Cheers,
> Bert
>
>
>
> Bert Gunter
>
> "The trouble with having an open mind is that people keep coming along
> and sticking things into it."
> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )
>
>
> On Tue, Jun 6, 2017 at 8:01 AM, Doran, Harold <[hidden email]> wrote:
> > I am writing a program where non-technical R users will read in a config file
> and the config file will then parse the arguments found within the config and
> pass them to respective functions. I'm having trouble (efficiently) writing a
> piece of code to retain quotation marks around the argument which requires
> it as input, as found in the example function below, myFuncton1.
> >
> > Below is a minimal, reproducible example of the issue with comments.
> >
> > ### This is a sample structure of the configuration file
> >
> > scoreConfig <- structure(list(Function = c("myFunction1", "myFunction1",
> "myFunction1",
> > "myFunction2", "myFunction2"), Argument = c("arg1", "arg2", "arg3",
> > "arg1", "arg2"), Value = c("5", "10", "Hello", "5", "10"), Class = c("numeric",
> > "numeric", "character", "numeric", "numeric")), .Names = c("Function",
> > "Argument", "Value", "Class"), class = "data.frame", row.names = c(NA,
> > -5L))
> >
> > ### Two sample functions, once of which requires a string
> > myFunction1 <- function(arg1, arg2, arg3 = c('Hello', 'Goodbye')){
> >         arg3 <- match.arg(arg3)
> >         result <- arg1 + arg2
> >         cat(arg3, result, '\n')
> >         }
> >
> >
> > myFunction2 <- function(arg1, arg2){
> >         result <- arg1 * arg2
> >         result
> >         }
> >
> >
> > ### Working Example.
> > ### myFunction2 works no problem
> > myFunction2Vals <- subset(scoreConfig, Function == 'myFunction2')
> > myOptions <- with(myFunction2Vals, paste(Argument, Value, sep = '=',
> collapse = ','))
> > eval(parse(text = paste( "myFunction2(", myOptions, ")" )))
> >
> >
> > ### myFunction1 fails
> > myFunction1Vals <- subset(scoreConfig, Function == 'myFunction1')
> > myOptions <- with(myFunction1Vals, paste(Argument, Value, sep = '=',
> collapse = ','))
> > eval(parse(text = paste( "myFunction1(", myOptions, ")" )))
> >
> > ### What I want is simply
> > myFunction1(arg1 = 1, arg2 = 2, arg3 = 'Hello')
> >
> > I'm curious if someone has a perspective on the most efficient way to
> automate this by using information provided in the 'Value" column, so
> perhaps conditional on that value it could wrap the name in quotes.
> >
> > I admit to running into a limit and am tapping out so to speak on the right
> way to do this.
> >
> > Thanks for any advice
> > Harold
> >
> > ______________________________________________
> > [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide http://www.R-project.org/posting-
> guide.html
> > and provide commented, minimal, self-contained, reproducible code.
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-
> guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.