Скрытие имен функций от результатов ls() - чтобы быстрее найти имя переменной

Когда мы определили десятки функций - возможно, для разработки нового пакета - трудно найти имя конкретной переменной среди многих имен функций через ls() команда.

В большинстве случаев мы не ищем имя функции - мы уже знаем, что они существуют - но мы хотим найти, какое имя мы присвоили переменной.

Любая идея, чтобы решить это высоко ценится.

6 ответов

Решение

Если вы хотите, чтобы функция делала это, вам нужно немного поиграться с окружением, которое 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() когда мы проверяем, являются ли они функцией или нет.

Так что возможно

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

Джош О'Брайен предложил использовать

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

Эта функция после некоторых преобразований и проверок вызывает

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

что довольно близко к тому, что я предложил в первую очередь, но хорошо упаковано в функцию setdiff,

Вместо того, чтобы сортировать объекты в вашей глобальной среде и пытаться отделить объекты данных от функций, было бы лучше хранить функции в другой среде, чтобы ls() не перечисляет их (по умолчанию он только перечисляет вещи в глобальной среде). Но они все еще доступны и могут быть перечислены при желании.

Лучший способ сделать это - создать пакет с функциями в нем. Это не так сложно, как иногда кажется, просто используйте package.skeleton начать.

Другой альтернативой является использование save функция, чтобы сохранить все ваши функции в файл, удалить их из глобальной среды, а затем использовать attach функция, чтобы прикрепить этот файл (и, следовательно, все функции) к пути поиска.

Итак, вы просто хотите имена переменных, а не функции? Это сделает это.

ls()[!sapply(ls(), function(x) is.function(get(x)))]

Следующая функция lsos ранее был опубликован в stackru ( ссылка) - он дает хороший порядок объектов, загруженных в 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

Я держу эту функцию в моем .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))
}
Другие вопросы по тегам