4

当我们定义了几十个函数时——可能是为了开发一个新的包——很难通过ls()命令从众多函数名中找出一个特定变量的名称。

在大多数情况下,我们不是在寻找函数名称——我们已经知道它们存在——但我们想找到我们分配给变量的名称。

任何解决它的想法都受到高度赞赏。

4

6 回答 6

5

如果您想要一个函数来执行此操作,您需要在ls()查看的环境中进行一些操作。在正常使用中,下面的实现将通过在函数的父框架中列出对象来工作,如果在顶层调用。

lsnofun <- function(name = parent.frame()) {
    obj <- ls(name = name)
    obj[!sapply(obj, function(x) is.function(get(x)))]
}

> ls()
[1] "bar"           "crossvalidate" "df"           
[4] "f1"            "f2"            "foo"          
[7] "lsnofun"       "prod"         
> lsnofun()
[1] "crossvalidate" "df"            "f1"           
[4] "f2"            "foo"           "prod"

我写了这个,所以你可以传入name参数,ls()如果你需要在一系列嵌套函数调用中调用这种方式。

还要注意,当我们测试它们是否是函数时,我们需要get()命名的对象。ls()

于 2012-10-26T21:12:40.147 回答
4

所以也许

ls()[!ls()%in%lsf.str()]

Josh O'Brien 的建议是使用

setdiff(ls(), lsf.str())

该函数,经过一些转换和检查,调用

x[match(x, y, 0L) == 0L]

这与我最初建议的非常接近,但在 function 中很好地打包了setdiff

于 2012-10-26T21:08:13.247 回答
4

与其对全局环境中的对象进行排序并尝试将数据对象与函数分开,不如将函数存储在不同的环境中以便ls()不列出它们(默认情况下它只列出全局环境中的东西)。但是它们仍然可以访问,并且可以根据需要列出。

最好的方法是制作一个包含函数的包。这并不像有时看起来那么难,只是package.skeleton用来开始。

另一种选择是使用该save函数将所有函数保存到文件中,从全局环境中删除它们,然后使用该attach函数将此文件(以及所有函数)附加到搜索路径。

于 2012-10-26T21:33:57.463 回答
1

所以你只想要变量名,而不是函数?这将做到这一点。

ls()[!sapply(ls(), function(x) is.function(get(x)))]
于 2012-10-26T21:04:57.610 回答
1

以下函数lsos之前发布在 stackoverflow (链接) - 它根据它们的大小对加载到 R 会话中的对象进行了很好的排序。函数的输出包含对象的类,您可以随后对其进行过滤以获取非函数对象。

source("lsos.R")

A <- 1
B <- 1
C <- 1
D <- 1
E <- 1
F <- function(x) print(x)

L <- lsos(n=Inf)
L[L$Type != "function",]

这将返回:

> lsos(n=Inf)
         Type Size Rows Columns
lsos function 5184   NA      NA
F    function 1280   NA      NA
A     numeric   48    1      NA
B     numeric   48    1      NA
C     numeric   48    1      NA
D     numeric   48    1      NA
E     numeric   48    1      NA

或者,使用过滤器,F不返回函数:

> L[L$Type != "function",]
     Type Size Rows Columns
A numeric   48    1      NA
B numeric   48    1      NA
C numeric   48    1      NA
D numeric   48    1      NA
E numeric   48    1      NA
于 2012-10-26T21:17:45.567 回答
0

我将此功能保留在我的.rprofile. 我不经常使用它,但是当我的全局环境中有多个环境、函数和对象时,它会很棒。显然不如 BenBarnes 的解决方案那么优雅,但我永远不必记住语法,并且可以lsa()根据需要调用。这也允许我列出特定的环境。例如lsa(e)

lsa <- function(envir = .GlobalEnv) {
    obj_type <- function(x) {
        class(get(x))
    }
    lis <- data.frame(sapply(ls(envir = envir), obj_type))
    lis$object_name <- rownames(lis)
    names(lis)[1] <- "class"
    names(lis)[2] <- "object"
    return(unrowname(lis))
}
于 2012-10-26T21:20:50.757 回答