将输入变量转换为字符串 - `deparse(substitute(x))` 不起作用

4
我正在尝试编写一个函数,它接收一个数据框并添加一个新变量,该变量为输入数据框的名称。例如:
foo <- data.frame(x = 1:10, y = rep(c("a", "b")))
mutate(foo, id = "foo") 

这似乎相对容易实现,因为它在这里的工作方式如下:

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

var_as_string(foo)

Result:
[1] "foo"

我本以为这样也可以,但事实并非如此:

add_id <- function(x) {
    mutate(x, id = deparse(substitute(x)))
}

add_id(foo)

Result:
   zz yy id
1   1  a  x
2   2  b  x
3   3  a  x
4   4  b  x
5   5  a  x
6   6  b  x
7   7  a  x
8   8  b  x
9   9  a  x
10 10  b  x

作为测试,我尝试了这个方法,但它并没有像我想象的那样起作用:
var_as_string2 <- function(x) {
  var_string <- var_as_string(x)
  var_string(x)
}

var_as_string2(foo)

Result:
[1] "x"

这个问题有解决方案吗?我是不是忽略了什么,或者对R中的函数有一个基本的误解?


mutate 可以来自于 dplyrplyr。我猜你想要一个基于 dplyr 的解决方案? - akrun
抱歉,我之前使用了 plyr... mutate 部分没有问题,但是在定义的函数中使用 deparse(substitute(x)) 时,变量名未被分配为 id - jdesilvio
通过创建与@konvas的函数相同的方式,deparse(substitute(对我有用。但是,我正在使用dplyr。即add_id <- function(x) {s <- deparse(substitute(x)); mutate(x, id = s)} - akrun
1个回答

3

使用 lazyeval 也许有更好的一行代码方法来实现这个,但是这种方法似乎可以工作。

add_id <- function(x) {
    s <- as.character(substitute(x))
    mutate(x, id = s)
}

add_id(foo)

与您尝试的方法相比,这个想法是您需要在mutate调用外部评估s

@akrun 说得好,如果OP正在使用评论中描述的plyr,最好坚持使用substitute - konvas
1
@akrun,lazyeval是为dplyr而设计的,但它本质上是一个通用的替代substitute的工具,用于处理未求值的参数。 - Konrad Rudolph
@Konrad:我尝试使用lazyeval - add_id_lazy <- function(x) { mutate(x, id = interp(~name, name = as.character(substitute(x)))) } 但是它没有起作用...你有什么想法吗? - jdesilvio
@Dixon11111 f = function (x) eval(interp(quote(mutate(x, id = y)), y = deparse(substitute(x)))) — 关键是使用 interp 将未求值的参数名注入到 mutate 表达式中,然后对其进行求值。或者,这里有一个更简单的解决方案,不需要使用 lazyeval(在 interp 的位置上,bquote 完全可以胜任):f = function (x) eval(bquote(mutate(x, id = .(deparse(substitute(x)))))) - Konrad Rudolph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接