Cast Function Argument as a Character String

Cast function argument as a character string?

foo <- function(x) deparse(substitute(x))

Converting R function argument into a string

I would suggest next approach which is closer to what you want. For sure you could modify it to obtain other outputs:

#Function
my_function <- function(x)
{
as.character(eval(parse(text=enquo(x)))[2])
}
#Apply
my_function(x = my_object)

Output:

[1] "my_object"

An improvement thanks to @MrFlick is next:

#Function
my_function <- function(x)
{
rlang::as_label(rlang::enquo(x))
}
#Apply
my_function(x = my_object)

Which produces same output with a more elegant style in the function:

[1] "my_object"

Using R, how to cast a character string as a function (e.g., using `as.function`)?

We could actually create a function called castAsFunction. We would need to give it not only a string as function body, but also the formal arguments. It feels like the function could be simplified, but it works with the example above.

FUN.n = "exp( 3 * x^2 + 2 * x + 1)"
x = -3:3

castAsFunction <- function(body, ...) {
dots <- match.call(expand.dots = FALSE)$...
form_ls <- rep(list(bquote()), length(dots))
names(form_ls) <- as.character(dots)
f <- function(){}
formals(f) <- form_ls
body(f) <- str2lang(body)
environment(f) <- parent.frame()
f
}

myfun <- castAsFunction(FUN.n, x)

myfun
#> function (x)
#> exp(3 * x^2 + 2 * x + 1)

myfun(x)
#> [1] 3.584913e+09 8.103084e+03 7.389056e+00 2.718282e+00 4.034288e+02
#> [6] 2.415495e+07 5.834617e+14

Created on 2021-02-18 by the reprex package (v0.3.0)

R : Define a function from character string

eval() and parse(), used together, may help you do what you want:

body <- "(x1 + x2) * x3"
args <- "x1, x2, x3"

eval(parse(text = paste('f <- function(', args, ') { return(' , body , ')}', sep='')))
# Text it:
f(3,2,5)
## 10

The explanation: parse() will return the parsed, but unevaluated, expression. I use the text argument in the function to pass a string to the parser. eval() will evaluate the parsed expression (in this case, it will execute the code block you've just parsed).

Hope this helps

Appropriate to cast string literal to char * in function argument?

Yes, avoid that. Now, if your function took a const char * there is nothing wrong with calling it with a string literal.

C++ compilers support string-literal to char * for backwards compatibility reasons only, and writing to a string literal results in undefined behavior.

When you do char bar[] = "Bar"; you are doing something fundamentally different (namely initializing an array of 4 characters with the values {'B', 'a', 'r', '\0'} that you are free to modify) than when you do char bar* = "Bar"; (where you are creating a non-const pointer to a 4 byte string that you may not modify).

In my opinion, you should never turn a string literal directly into a char*, instead put it into a const char* then (if you are communicating with a legacy API) explicitly const_cast<char*> the constness away, with a comment saying you are talking to a legacy API that has guarantees not to change the chars. The advantage of this is you can search your program for those const_casts when the API is upgraded, or you want to find where the segmentation fault involving writing to a char* came from.

One could even wrap the legacy API with const char* versions that do the const_cast within them.

The absolute worst situation would be having a bunch of char*s hanging around, some of them writable, others from string literals.



Related Topics



Leave a reply



Submit