我很困惑将值视为变量,以及何时将其视为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中的事情怎么做?
答案 0 :(得分:3)
在您的示例中,a$b
是a[["b"]]
的合成糖。当与列表一起使用时,这是$
符号的特殊功能。第二种形式符合您的预期 - a[[b]]
将返回a
的元素,其名称== 变量b的值,而不是名称为的元素是“b”。
数据框架类似。对于数据框a
,$
运算符引用列名称。因此a$b
与a[ , "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"))