存在和流行:为什么这些功能不同?

时间:2015-06-17 00:50:51

标签: r scope sapply

为什么下面的两个函数fngn不同?我不认为他们应该,但我必须遗漏一些东西。

vars <- letters[1:10]
a <- b <- 1
fn <- function (d) {
    sapply( vars, exists )
}
gn <- function (d) {
    sapply( vars, function (x) { exists(x) } )
}
fn(d=2)
#    a     b     c     d     e     f     g     h     i     j 
# TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE 
gn(d=2)
#    a     b     c     d     e     f     g     h     i     j 
# TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE 
exists("i")
# [1] FALSE

有两点不同:

  1. gn(d=2)d存在,但为什么不fn(d=2)
  2. fn(d=2)表示当i没有gn(d=2)时,i存在。这很令人费解,因为我没有在任何地方定义context.xml
  3. 注意:这是在R版本3.2.0上,似乎第二个行为是该版本的新功能(见下文)。

4 个答案:

答案 0 :(得分:6)

为什么i不同......

看起来R 3.2有变化。索引变量i一直是lapply的{​​{3}}(sapply实际调用的是fn。这与新行为一起强制评估传递给您正在应用的函数的参数。这意味着您现在可以访问循环中当前迭代的索引。

gnexists()行为不同的原因是fn在调用它的环境中查找。对于i,这是创建此gn变量的环境。在i的情况下,它会查看您的匿名函数的环境。当R在本地环境中找不到符号时,它会根据定义的函数位置搜索环境,而不是调用它们的位置。这意味着R将找不到i变量,因为您的匿名函数是在idx <- function() get("i", parent.frame(2)) sapply(letters[1:3], function(x) paste(idx(), x)) # a b c # "1 a" "2 b" "3 c" 变量不存在的地方定义的。

我们可以编写一个小帮助函数,以便更容易获取当前索引。

d

据我所知,这是目前无证件的行为。它可能会在R的未来版本中发生变化。

为什么d不同......

exists变量的差异是一个更直接的范围问题。 R再次创建了一个用于调用函数exists的新环境。此环境的父级是基础环境。因此,当您致电i时,它会查看调用它的位置(这是d存在的环境),并且由于它在那里找不到fn <- function (d) { sapply( vars, exists, where=environment() ) } fn(d=2) # a b c d e f g h i j # TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE ,它会搜索下一个父级这是基础环境。从不搜索当前的功能环境。您可以使用

显式搜索当前环境
library(ggplot2)
ggplot("your dataframe") + geom_point(aes(x = Latitude, y = Longitude, colour = factor(ACTIVITY)))

有关R中环境的更多信息,建议您阅读added to the current environment

答案 1 :(得分:1)

重要的区别是&#34; d&#34;的值,即调用中形式变量的名称。 。 exists功能的默认设置是查看&#34;以上&#34;不是&#34;在&#34;。在第一个实例中,.GlobalEnv中没有&#34; d&#34; -named实体,这是调用函数的地方。在第二个实例中,周围环境中有d(作为名称)。

正在寻找&#34;我&#34;或&#34; c&#34;找到函数c或for循环的索引。 (索引变量在for循环结束时仍然存在。)

似乎&#34; i&#34;价值差异仅在我在本机中没有看到的最新版本中,因为它与我当前的操作系统版本的最大值是3.1.3。也可能发生在那些使用过&#34; i&#34;作为当前会话中for循环的索引变量(或者正在使用之前保存的环境。)

答案 2 :(得分:0)

关于i,我无法重现它。但我会尝试解释其他差异,首先是两个函数找到的c和只有d找到的gn()

两个函数都找到c,因为它们找到了基函数c

现在对于d,R是词法范围的。您可能希望查看此问题Environments in R, mapply and get。因此,在第一个函数fn()中,exists并未在d的本地环境中查找fn(),而是在全局环境中(并且没有#&} 39; ta d那里。

但请注意,在gn()中,您使用exists()作为gn()内的匿名函数定义了该函数。看:

gn <- function (d) {
    sapply( vars, function (x) { exists(x) } ) # defined anon function
}

因此gn()的环境是匿名函数function (x) { exists(x) }的父环境。这就是为什么它在gn内搜索并找到本地参数d,返回TRUE

答案 3 :(得分:0)

这是奇怪的行为。我确信它有合理的解释。这是一个全新的R会议。我这次甚至没有使用RStudio,它产生相同的输出。

R version 3.2.0 (2015-04-16) -- "Full of Ingredients"
Copyright (C) 2015 The R Foundation for Statistical Computing

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> exists('i')
[1] FALSE
> sapply('i', exists)
   i 
TRUE 

更奇怪的行为:

> lapply('i', exists)
[[1]]
[1] TRUE

> vapply('i', exists, logical(1))
   i 
TRUE 
> tapply('i', 'i', exists)
   i 
TRUE 
> mapply(exists, list('i'))
[1] FALSE
> rapply(list('i'), exists)
[1] FALSE
> exists('i')
[1] FALSE
> ls()
character(0)

mapplyrapply都返回FALSE。它们都需要列表作为参数。这可能与它有关。也许其他应用函数正在R中的某些环境中选择一些东西,而裸函数和一些应用函数则没有。