Remove all R Data objects from Global Environment - r

I need a function to remove all objects on Data field of Global Environment (the one highlighted below).
I don't know specifically all classes of objects that appears there, however, I would like to remove everything, except for vectors, integers and functions.
Thanks in advance.

The data tab seems to hold anything with more than one dimension.
If you do ls(), you get character strings of the names of all the objects in the global environment. You can represent any of these objects by calling get("object_name"), so you can get the number of dimensions it has by calling length(dim(get("object_name"))). If this value is greater than 1, you know this is one of the objects you want to remove.
Therefore, all you need to do is apply length(dim(get("object_name"))) > 1 to the names of the global objects, as obtained by ls(). You can do this with sapply:
rm(list = ls()[sapply(ls(), function(x) length(dim(get(x))) > 1)])

Use the below code: in place of those variables you want to keep place in quotes see below example.
rm(list=setdiff(ls(), "keep_variable"))
Another option is to change list to grid and click on the variables you don't want and press clean button. That will remove all unwanted variables.

Related

Object modification only happens in list

I have put objects that I would like to edit in a list.
Say, the names of the objects are kind of like this:
name1_X
name1_Y
name2_X
name2_Y
And there are different sets of these objects, that are stored in different lists, so for each different set, they would have a slightly different name, like:
name1_P_X
name1_F1_X
name2_F2_Y
and so on..
So for every "name" there are six objects. There are two each ending with X or Y for P, F1, F2. We have three lists (listbF_P, listbF_F1, listbF_F2), each containing objects that end with X and Y.
I edited the objects in the list like this (example for only one list):
for (i in 1:NROW(listbF_P)){
listbF_P[[i]]#first.year <- 1986
listbF_P[[i]]#last.year <- 2005
listbF_P[[i]]#year.aggregate.method <- "mean"
listbF_P[[i]]#id <- makeFieldID(listbF_P[[i]])
}
When I check whether the changes were successfully applied, it works but only when referring to the objects inside the list but not the same objects "unlisted".
So if I call
listbF_P[[1]]#last.year
it returns
"2005"
But if I call
name1_X#last.year
it returns
"Inf"
The problem with this is that I want the edited objects in a different list later.
So I need either a way that the latter call example returns "2005" or a way that I can search for a certain object name pattern in multiple lists to put the ones that fit the pattern into another list.
This is because the example above was made with multiple lists (listbF_P, listbF_F1, listbF_F2) and these lists contain a pattern matching "X" and another matching "Y".
So basically I want to have two lists with edited objects, one matching pattern "X" and the other matching pattern "Y".
I would call the list matching the desired patterns like this:
listbF_ALL_X <- mget(ls(pattern=".*_X$"))
listbF_ALL_Y <- mget(ls(pattern=".*_Y$"))
The first list would hence contain all objects ending with "X", e.g.:
name1_P_X
name1_F1_X
name1_F2_X
name2_P_X
[...]
and I would like to have the ones that I edited in the loop earlier
..but when calling the objects out of that list
listbF_ALL_X[[1]]#last.year
again just returns
"Inf"
since it takes the objects out of the environment and not the list. But I want it to return the desired number that has been changed (e.g. "2005").
I hope my problem and the two possible ways of solving them are clear..
If something isn't, ask :)
Thanks for any input
Regards
In R, unlike in many other modern languages, (almost) all objects are logically copies of each other. You can’t have multiple names that are references to the same object (see below for caveats).
But even if this was supported, your design looks confusing. Rather than have lots of related objects with different names, put your objects into nested lists and classes that logically relate them. That is, rather than have objects with names name{1..10}_{P,F1,F2}_{X,Y}, you should have one list, name, in which you store nested lists or classes with named members P, F1, F2 which, in turn, are objects that have names X and Y. Then you could access an object by, say, name[1L]$P$X (or name[1L]#P#X, if you’re using S4 objects with slots).
Or you use a more data-oriented approach and flatten all these nested objects into a table with corresponding columns P, F1, F2, X and Y. Which solution is more appropriate depends on your exact use-case.
Now for the caveat: you can use reference semantics in R by using *environments8 instead of regular objects. When copying an environment, a reference to the same environment object is created. However, this semantic is usually confusing because it’s contrary to the expectation in R, so it should be used with care. The ‘R6’ package creates an object system with reference semantics based on environments. For many purposes where reference semantics are indispensable, ‘R6’ is the right answer.
I found another solution:
I went on by modifying this part:
listbF_ALL_X <- mget(ls(pattern=".*_X$"))
listbF_ALL_Y <- mget(ls(pattern=".*_Y$"))
To not call objects from the environment but by calling objects from each list:
listbF_ALL_X <- c(c(listbF_P, listbF_F1, listbF_F2)[grepl(".*_X$", names(c(listbF_P, listbF_F1, listbF_F2)))])
listbF_ALL_Y <- c(c(listbF_P, listbF_F1, listbF_F2)[grepl(".*_Y$", names(c(listbF_P, listbF_F1, listbF_F2)))])
It's not the prettiest way of doing it but it works and in my case it was the solution that required the least amount of change in my script.

How to delete all "Values" in RStudio Environment?

I know that rm(list=ls()) can delete all objects in the current environment.
However, environment has three categories: Data, Values, Functions. I wonder how I can only delete all the objects in one particular category? Something like
rm(list=ls(type="Values"))
You could use ls.str to specify a mode, or lsf.str for functions. The functions have print methods that make it look otherwise, but underneath are just vectors of object names, so
rm(list = lsf.str())
will remove all user-defined functions, and
rm(list = ls.str(mode = 'numeric'))
will remove all numeric vectors (including matrices). mode doesn't correspond exactly to class, though, so there's no way to distinguish between lists and data.frames with this method.
One option is that you can change the view to grid view and check all the boxes next to the ones you want to delete and click the broom button.
So far as I'm aware, Data, Values and Functions are terms used by the RStudio interface. Data = variables with dimensions e.g. data frames, matrices, Values = other variables (e.g. vectors). They are not terms that can be accessed via R code.

How to dynamicly create variables inside a list of dataframes in R

got a list named x which has 25 elements. Each of which is named after a country. Inside each country i have 10-20 variables and i want to create a new one inside each dataframe which uses one already existing variable (lets name it y) to create a new variable.
closest i have come to solving it is using a for loop but using the [[<- creates newvariables outside the list (which is too much of a hustle to put in again) with "[[" in their name.
also assign doesnt work either due to invalid first argument error (propably due to my effort to dynamically create them)
i guess a nested lapply is the best option but being new to R dont know how that would work
We can loop over the list with lapply and transform to create a new variable
lapply(lst, transform, newVar = y)
I do not really understand your question, could you paste some code and say what you'd like to see. When I have to create variables names dynamically I use trick as the one below:
names(tmp) = paste('y', 1:25, sep='')
If you search help(names) you should get how to change columns and row names specifically. Paste is just a way to concatenate different types of text you want into your variable names

Working with "..." input in R function

I am putting together an R function that takes some undefined input through the ... argument described in the docs as:
"..." the special variable length argument ***
The idea is that the user will enter a number of column names here, each belonging to a dataset also specified by the user. These columns will then be cross-tabulated in comparison to the dependent variable by tapply. The function is to return a table (independent variable x indedependent variable).
Thus, I tried:
plotter=function(dataset, dependent_variable, ...)
{
indi_variables=list(...); # making a list of the ... input as described in the docs
result=with (dataset, tapply(dependent_variable, indi_variables, mean); # this fails
}
I figured this should work as tapply can take a list as input.
But it does not in this case ('Error in tapply...arguments must have same length') and I think it is because indi_variables is a list of strings.
If I input the contents of the list by hand and leave out the quotation marks, everything works just fine.
However, if the user feeds the function the column names as non-strings, R will interpret them as variable names; and I cannot figure out how to transform the list indi_variables in the right way, unsuccessfully trying things like this:
indi_variables=lapply(indi_variables, as.factor)
So I am wondering
What causes the error described above? Is my interpretation correct?
How would one go about transforming the list created through ... in the right way?
Is there an overall better way of doing this, in the input or the implementation of tapply?
Any help is much appreciated!
Thanks to Joran's helpful reading, I have come up with these improvements than make things work out...
indi_variables=substitute(list(...));
result=with (dataset, tapply(dependent_variable, eval(indi_variables, dataset), FUN=mean));

How to remember which variables are in a list

I have a huge list in which I put different variables in order to apply the same function to all of them.
In a next step I want to apply specific functions to specific elements of the list, i.e. all functions used vary from element to element within the list.
How can I do this? My first idea was (see my other question, Reassign variables to elements of list) to split the list into the original variables again. This can be done.
But I was recommended to keep the items in the list instead. My questions is: How can I access each variable quickly by doing that? One idea would be to use the names attribute of the list in the beginning and fill it with a vector of the original variable names. However, by doing that it would be much longer later on to type list["name_x"] than just typing name_x assuming name_x is globally available.
What is the most efficient way to deal with my problem?

Resources