5

How can I use rm to remove all objects of a certain type in R?

I currently have a bunch of functions defined that I'd like to expunge.

I know ls has a pattern option, but this would only help if I was naming all the functions in a pattern (I'm not).

MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
  • Might be a dupe of http://stackoverflow.com/questions/28142088/exclude-or-keep-only-data-frames-from-the-global-environment-in-r – Rich Scriven Apr 22 '16 at 20:38

5 Answers5

8

A variation on @Jilber's answer:

rm(list=names(Filter(is.function, mget(ls(all=T)))))
BrodieG
  • 51,669
  • 9
  • 93
  • 146
3

My solution is basically to use mget to get the class of everything in ls(), then subset ls() according to when class=="function":

rm(list=ls(all=TRUE)[sapply(mget(ls(all=TRUE)), class) == "function"])

@Jilber suggests a cleaner alternative:

rm(list=ls(all=TRUE)[sapply(mget(ls(all=TRUE)), is.function)])

These basic approaches can be expanded to accommodate more complex "genocide" (class-specific purging):

rm(list=ls(all=TRUE)[sapply(mget(ls(all=TRUE)), class) %in% 
    c("function", "numeric")])
rm(list=ls(all=TRUE)[sapply(mget(ls(all=TRUE)),
                            function(x) is.function(x) | is.numeric(x))])

@Jilber's approach also has the advantage that it will catch multi-class objects (most notably, data.tables.

Suppose we wanted to remove all data.frames that are not (also) data.tables:

rm(list=ls(all=TRUE)[sapply(mget(ls(all=TRUE)),
                            function(x) is.data.frame(x) & !is.data.table(x))])
MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
  • 1
    You can also use `is.function` as in `rm(list=ls()[sapply(mget(ls()), is.function)])`. – Jilber Urbina Jun 10 '15 at 21:40
  • That's perfect for the specific question of removing `function`s, I've edited it in. My solution is slightly more flexible--for example, if I wanted to find `function`s _and_ `data.frame`s--though yours could be bent to this end as well. – MichaelChirico Jun 10 '15 at 21:50
  • @Jilber your approach also raises the point that mine will struggle to differentiate `data.table` and `data.frame` (and any other object type that has `length(class(x))>1` – MichaelChirico Jun 10 '15 at 21:59
3

You may try ls.str where you can list objects of a certain mode (e.g. integer, list (data frame) or function), or lsf.str (returns functions only):

# some objects to 'look for'
int1 <- 1
char1 <- "a"
list1 <- data.frame(x1, x2)
fun1 <- function() x1 + x2

# ls()
# ls.str()
ls.str(mode = "function")
funs <- as.character(ls.str(mode = "function"))

lsf.str()
funs <- as.character(lsf.str())

# rm(funs)
Henrik
  • 65,555
  • 14
  • 143
  • 159
3

There is an ls.str() function that accepts a mode argument. You can get all the functions in the global environment with:

ls.str( mode="function")  # or in a different environment if properly created

The exists function tests whether it can be found and can be limited to particular mode. This is a potentially destructive effect on a running session

rm( list = ls()[ sapply( ls(), exists, mode="function")] )
# test for errors and effectiveness
any( sapply( ls(), exists, mode="function"))
# [1] FALSE

If you were trying to remove only functions with particular patterns to their names you might select among the character vectors returned by ls() with grepl.

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Can you think of a way for this be adjusted to accommodate more complicated type requests? e.g. `function` _or_ `numeric`, _not_ `data.frame`, etc? – MichaelChirico Jun 10 '15 at 22:46
  • 1
    Just make the function that tests for mode capable of handling other modes. The mode of a data.frame would be "list". It would require as many calls to exists as you have options in mind. – IRTFM Jun 11 '15 at 00:16
2

If you have Dirk's lsos function (also available in the stackoverflow package), then you could do this:

rm(list=rownames(subset(lsos(), Type == "POSIXct")))

This might be useful if the class doesn't have a builtin predicate for type checking (such as is.function)

Community
  • 1
  • 1
Neal Fultz
  • 9,282
  • 1
  • 39
  • 60
  • Thanks, that this is more general is great! I am always averse to installing packages, though; anyway, a more specialized version of this would do just fine. – MichaelChirico Jun 11 '15 at 20:44