R中变量的内联扩展

时间:2013-05-10 15:38:34

标签: r

我很困惑将值视为变量,以及何时将其视为R中的字符串。在Ruby和Python中,我习惯于一个总是必须引用的字符串,并且始终会处理不带引号的字符串作为变量。 IE浏览器。

a["hello"] => a["hello"]
b = "hi"
a[b] => a["hi"]

但在R中,情况并非如此,例如

a$b < c(1,2,3)

b这里是列的值/名称,而不是变量b。

c <- "b"
a$c => column not found (it's looking for column c, not b, which is the value of the variable c)

(我知道在这种特殊情况下我可以使用[c],但还有很多其他情况。例如ggplot(a, aes(x=c)) - 我想绘制的是c的值,而不是名称c)......

在其他StackOverflow问题中,我看过引用,替代等提到的内容。

我的问题是:是否有一种通用的方法来“扩展”变量并确保使用变量的值而不是变量的名称?或者这不是R中的事情怎么做?

5 个答案:

答案 0 :(得分:3)

在您的示例中,a$ba[["b"]]的合成糖。当与列表一起使用时,这是$符号的特殊功能。第二种形式符合您的预期 - a[[b]]将返回a的元素,其名称== 变量b的值,而不是名称为的元素是“b”。

数据框架类似。对于数据框a$运算符引用列名称。因此a$ba[ , "b"]相同。在这种情况下,要引用a所指示的b列,请使用a[, b]

答案 1 :(得分:3)

你发布的关于$运算符的内容不起作用的原因是非常微妙的,并且通常与R中的大多数其他情况完全不同,你可以使用像{{1}这样的函数这是为此目的而设计的。但是,调用get等同于调用

a$b

这提醒我们,在R中,所有都是一个对象。 `$`(a , b) 是一个函数,它需要两个参数。如果我们检查源代码,我们可以看到调用$并期望R将a$c评估为c从不工作,因为在源代码中它指出:

"b"

使用以下方法实现此目的:

/* The $ subset operator.  
   We need to be sure to only evaluate the first argument.  
   The second will be a symbol that needs to be matched, not evaluated.  
*/

if(isSymbol(nlist) ) SET_STRING_ELT(input, 0, PRINTNAME(nlist)); else if(isString(nlist) ) SET_STRING_ELT(input, 0, STRING_ELT(nlist, 0)); else { errorcall(call,_("invalid subscript type '%s'"), type2char(TYPEOF(nlist))); } 是您传递的参数nlist(C函数的名称do_subset_3映射到),在本例中为$。它发现c是一个符号,因此它用字符串替换它但不评估它。如果它是一个字符串,那么它将作为字符串传递。

答案 2 :(得分:2)

以下是一些链接,可以帮助您了解R中的“为什么和何时”进行评估。它们可能具有启发性,甚至可能有所帮助,如果没有别的,它们会让您知道您并不孤单:

http://developer.r-project.org/nonstandard-eval.pdf

http://journal.r-project.org/2009-1/RJournal_2009-1_Chambers.pdf

http://www.burns-stat.com/documents/presentations/inferno-ish-r/

在最后一个中,最重要的部分是项目符号2,然后阅读整套幻灯片。我可能会从第3个开始,然后是第2个。

这些不太注重如何使具体案例发挥作用(正如其他答案所做的那样),更多的是本着导致这种状况的精神,以及为什么在某些情况下有标准是有道理的访问变量的非标准方式。希望了解原因和时间将有助于整体做什么。

答案 3 :(得分:0)

如果要获取名为“b”的变量,请在每种情况下使用get函数。无论在何处找到,都会将b的值替换为get(b)。

答案 4 :(得分:0)

如果你想玩表达式,你需要使用quote(),substitute(),bquote()和你提到的朋友。

例如:

x <- quote(list(a = 1))
names(x) # [1] ""  "a"
names(x) <- c("", a)
x # list(foo = 1)

c <- "foo"
bquote(ggplot(a, aes(x=.(c)))) # ggplot(a, aes(x = "foo"))
substitute(ggplot(a, aes(x=c)), list(c = "foo"))