When we have defined tens of functions - probably to develop a new package - it is hard to find out the name of a specific variable among many function names through ls()
command.
In most of cases we are not looking for a function name - we already know they exist - but we want to find what was the name we assigned to a variable.
Any idea to solve it is highly appreciated.
If you want a function to do this, you need to play around a bit with the environment that ls()
looks in. In normal usage, the implementation below will work by listing objects in the parent frame of the function, which will be the global environment if called at the top level.
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"
I've written this so you can pass in the name
argument of ls()
if you need to call this way down in a series of nested function calls.
Note also we need to get()
the objects named by ls()
when we test if they are a function or not.
Rather than sorting through the objects in your global environment and trying to seperate data objects from functions it would be better to store the functions in a different environment so that ls()
does not list them (by default it only lists things in the global environment). But they are still accessible and can be listed if desired.
The best way to do this is to make a package with the functions in it. This is not as hard as it sometimes seems, just use package.skeleton
to start.
Another alternative is to use the save
function to save all your functions to a file, delete them from the global environment, then use the attach
function to attach this file (and therefore all the functions) to the search path.
So perhaps
ls()[!ls()%in%lsf.str()]
Josh O'Brien's suggestion was to use
setdiff(ls(), lsf.str())
That function, after some conversions and checks, calls
x[match(x, y, 0L) == 0L]
which is pretty close to what I suggested in the first place, but is packed nicely in the function setdiff
.
The following function lsos
was previously posted on stackoverflow (link) - it gives a nice ordering of objects loaded in your R session based on their size. The output of the function contains the class of the object, which you can subsequently filter to get the non-function objects.
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",]
This returns:
> 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
Or, with the filter, the function F
is not returned:
> 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
So you just want the variable names, not the functions? This will do that.
ls()[!sapply(ls(), function(x) is.function(get(x)))]
I keep this function in my .rprofile
. I don't use it often but it's great when I have several environments, function and objects in my global environment. Clearly not as elegant as BenBarnes' solution but I never have to remember the syntax and can just call lsa()
as needed. This also allows me to list specific environments. e.g. 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))
}
来源:https://stackoverflow.com/questions/13094324/hiding-function-names-from-ls-results-to-find-a-variable-name-more-quickly