首页 > 解决方案 > 在R中的`$`登录后使用替代品

问题描述

我想知道是否有一种方法可以G在下面的代码中像工作$一样D$post == 1工作?

D <- data.frame(post = 1:10, out = 2:11)

G <- substitute(post == 1)

D$G    ## can we make `G` to work like `D$post`?

D$post == 1  ## Works

标签: rfunctionsubset

解决方案


你可以这样做:

G <- substitute(post == 1)
E <- substitute(D$G, list(G = G))
#D$post == 1

那个表情看起来像你想要的,对吧?好吧,事实并非如此,正如您在尝试评估它时所看到的那样:

eval(E)
#Error in D$post == 1 : invalid subscript type 'language'

让我们更详细地检查表达式:

as.list(E)
#[[1]]
#`$`
#
#[[2]]
#D
#
#[[3]]
#post == 1

好的,我们有一个$带有两个参数(D和)的函数调用(to post == 1)。第二个参数是一个表达式,而$需要一个名称。

让我们将其与它的外观进行比较:

as.list(quote(D$post == 1))
#[[1]]
#`==`
#
#[[2]]
#D$post
#
#[[3]]
#[1] 1

as.list(quote(D$post == 1)[[2]])
#[[1]]
#`$`
#
#[[2]]
#D
#
#[[3]]
#post

所以,D$post == 1实际上是对两个嵌套函数的调用,get 被解析为:

`==`(`$`(D, post), 1)

我希望这能阐明为什么“[w]在 $ 符号之后使用替代品”不是那么简单。

如果您了解表达式的解析方式,只是为了表明这仍然是可能的:

E <- quote(D$x)
E[[3]] <- G[[2]]
G[[2]] <- E
eval(G)
#[1]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

然而,这样的代码真的很难维护和调试。不要这样做。

正如@joran 所示,您可以使用类似的函数with来评估post == 1data.frame 中的表达式,这基本上只是 eval(G, D, parent.frame()). 然而,这是一条危险而滑溜的道路,可能会导致龙。help("subset")让我从这里引用相关警告:

这是一个旨在以交互方式使用的便利功能。对于编程,最好使用像 [ 之类的标准子集函数,特别是参数子集的非标准评估可能会产生意想不到的后果。


推荐阅读