r-如何防止`..`消失在部门内部(替换(x))



短版本

考虑这个功能:

my_fun <- function(x){
deparse(substitute(x))
}

如果只添加了一个变量名,为什么函数会删除`if?请参阅此处:

my_fun(`bad name`)
"bad name"
my_fun(`bad name` - 1)
"`bad name` - 1"

长版本

我写了一个简单的函数,它接受一个数据帧,并对选定的列进行一些转换。这就是功能:

my_fun <- function(data, transform){
transform <- deparse(substitute(transform))
transform <- unlist(strsplit(transform, "\+"))
out <- do.call("cbind.data.frame", lapply(transform, function(transform_i){
eval(parse(text= transform_i), data)
}))
names(out) <- transform
return(out)
}

有了这个功能,我们可以做这样的事情:

# Create data.
df <- data.frame(matrix(rep(1:4, 2), ncol= 2))
names(df) <- c("good_name", "bad name")
# Transform data with function.
my_fun(df, sqrt(good_name) + sqrt(`bad name`) - 1)
sqrt(good_name)   sqrt(`bad name`) - 1
1         1.000000             0.0000000
2         1.414214             0.4142136
3         1.732051             0.7320508
4         2.000000             1.0000000

但是,如果我们输入一个包含空格的名称,函数将失败,如这里所示:my_fun(df,`bad-name`(。我注意到deparse(substitute(transform))删除了"如果我不进行转换"。请参阅此处:

my_fun <- function(data, transform){
deparse(substitute(transform))
}
my_fun(df, `bad name`)
"bad name"
my_fun(df, `bad name` -1)
"`bad name` - 1"

如何阻止deparse(substitute(transform))删除`?

我知道有很多方法可以像我的函数一样转换数据帧。例如,我们可以在这里使用with(df,`bad-name`-1(和with(df、`bad-name](。但这不是问题所在。

从帮助文件?default:回溯选项的默认值是不引用单个符号,而仅引用复合表达式。这篇SO文章提示查看?Quotes帮助文件——如果需要,我们可以使用反斜杠转义反斜杠。

在本例中,可以尝试将deparse函数的backtick参数设置为TRUE。要比较不同的方法,以及组合是如何分开的,请考虑以下情况:

substitute(`bad name`)
#> `bad name`
deparse(substitute(`bad name`))
#> [1] "bad name"
deparse(substitute(`bad name`), backtick = T)
#> [1] "`bad name`"
# and see this fail:
substitute(`bad name)
# and this return
deparse(
deparse(substitute(`bad name`))
)
#> ""bad name""
deparse(substitute(
`deparse(substitute(bad name))`
))
#> [1] "deparse(substitute(bad name))"
deparse(substitute(
`deparse(substitute(`bad name`))`
))
#> Error: unexpected symbol in:
#> "deparse(substitute(
#>  `deparse(substitute(`bad"
#> > ))
#> Error: unexpected ')' in ")"
# but
deparse(substitute(
`deparse(substitute(`bad name`))`
))
#> [1] "deparse(substitute(`bad name`))"

如果目的是强制使用字符名,请查看R4.0.0(2020年4月(及更高版本的deparse1

最新更新