Скрытие имен функций от результатов 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))
}