Phil
Phil

Reputation: 8107

Removing objects in R environment that do not fit a criteria

I ran a loop that iterated through and created a bunch of objects whose names all start with "results_" and that are of differing nrow lengths, many of which are 0.

To make this list of objects easier to handle, I'd like to remove any objects whose nrow is equal to 0. I've tried below a variety of solutions provided for similar questions to this one, but none worked for my particular case. What am I doing wrong?

Attempt 1: rm(list=ls(all=TRUE)[sapply(mget(ls(all=TRUE)), function(x) nrow(x) == 0)])

Attempt 2: rm(list=ls()[!sapply(mget(ls(),.GlobalEnv), function(x) { nrow(x) == 0 } )])

Attempt 3:

rm(list=
    Filter(
        Negate(is.na),                                  # filter entries corresponding to objects that don't meet function criteria   
        sapply(
            ls(pattern="^results_"),                     # only objects that start with "results_"
            function(x) if(nrow(x) == 0) x else NA   # return names of objects of nrow length 0
        )))

Upvotes: 2

Views: 118

Answers (2)

R-addict
R-addict

Reputation: 7

Concerning your problem, my suggestion would be to store all your objects inside a list and then mine this list for objects with nrow == 0. This is much easier than trying to work with variable names since ls() function returns only the names as characters and not the object in itself so you would need to find a way to call them after. Below I've posted a short toy example on how to do that with a list where the first matrix is nrow == 0. Hope this will help you. Best regards,


superList=c() #define a list to store your objects
for(i in 0:5){ #generate them and store them in your list, the first matrix has nrow = 0
  item=matrix(nrow = i,ncol=2)
  superList[[i+1]]=item
  print(i)

}
toErase=sapply(superList,function(x) nrow(x)==0)  #scan your list to find object with nrow==0
superList=superList[-which(toErase==TRUE)] #remove them from your list
sapply(superList,function(x) nrow(x)) #check that the first matrix

Upvotes: 0

d.b
d.b

Reputation: 32548

I'd go with get as it returns the object instead of putting it in a list. Try

rm(list = ls(pattern = "results_")[sapply(ls(pattern = "results_"), function(x)
                                                                    NROW(get(x))) == 0])

Example

results_1 = data.frame(x = 1:5)
results_2 = data.frame(x = numeric(0))
NROW(results_1)
#[1] 5
NROW(results_2)
#[1] 0
ls()
#[1] "results_1" "results_2"
rm(list = ls(pattern = "results_")[sapply(ls(pattern = "results_"), function(x)
                                                                    NROW(get(x))) == 0])
ls()
#[1] "results_1"

Upvotes: 2

Related Questions