This question already has an answer here:
How to call an object with the character variable of the same name
(1 answer)
Closed 7 years ago.
I have some sequentially labeled data frames i.e frame_1 frame_2 e.t.c... I would like to access them in a sequential manner possibly using a loop
one way that makes sense to me is to assign the name of the data frame I want to access to an object, then pass that object to a function i.e
varname<-paste("frame_",1,_sep="")
then call my function
function(varname)
But R appears to call the function on a string varname, and not the object with the same name as varname.
Is there way I can do what I want?
Thanks.
I found out you can parse a string as an R command using a combination of eval and parse, so for instance :
function( eval( parse(text=paste0("name_",1))) )
In a loop:
for( i in 1:length(holder)){
function(eval( parse(text=paste0("frame_",i))) )
}
Related
My question refers to redundant code and a problem that I've been having with a lot of my R-Code.
Consider the following:
list_names<-c("putnam","einstein","newton","kant","hume","locke","leibniz")
combined_df_putnam$fu_time<-combined_df_putnam$age*365.25
combined_df_einstein$fu_time<-combined_einstein$age*365.25
combined_df_newton$fu_time<-combined_newton$age*365.25
...
combined_leibniz$fu_time<-combined_leibniz$age*365.25
I am trying to slim-down my code to do something like this:
list_names<-c("putnam","einstein","newton","kant","hume","locke","leibniz")
paste0("combined_df_",list_names[0:7]) <- data.frame("age"=1)
paste0("combined_df_",list_names[0:7]) <- paste0("combined_df_",list_names[0:7])$age*365.25
When I try to do that, I get "target of assignment expands to non-language object".
Basically, I want to create a list that contains descriptors, use that list to create a list of dataframes/lists and use these shortcuts again to do calculations. Right now, I am copy-pasting these assignments and this has led to various mistakes because I failed to replace the "name" from the previous line in some cases.
Any ideas for a solution to my problem would be greatly appreciated!
The central problem is that you are trying to assign a value (or data.frame) to the result of a function.
In paste0("combined_df_",list_names[0:7]) <- data.frame("age"=1), the left-hand-side returns a character vector:
> paste0("combined_df_",list_names[0:7])
[1] "combined_df_putnam" "combined_df_einstein" "combined_df_newton"
[4] "combined_df_kant" "combined_df_hume" "combined_df_locke"
[7] "combined_df_leibniz"
R will not just interpret these strings as variables that should be created and be referenced to. For that, you should look at the function assign.
Similarily, in the code paste0("combined_df_",list_names[0:7])$age*365.25, the paste0 function does not refer to variables, but simply returns a character vector -- for which the $ operator is not accepted.
There are many ways to solve your problem, but I will recommend that you create a function that performs the necessary operations of each data frame. The function should then return the data frame. You can then re-use the function for all 7 philosophers/scientists.
I'm parsing a JSON using the RJSONIO package.
The parsed item contains nested lists.
Each item in the list can be extracted using something like this:
dat_raw$`12`[[31]]
which correctly returns the string stored at this location (in this example, the '12' refers to the month and [[31]] to day).
"31-12-2021"
I now want to run a for loop to sequentially extract the date for every month. Something like this:
for (m in 1:12) {
print(dat_raw$m[[31]])
}
This, naturally, returns a NULL because there is no $m[[31]] in the list.
Instead, I'd like to extract the objects stored at $`1`[[31]], $`2`[[31]], ... $`12`[[31]].
There must be a relatively easy solution here but I haven't managed to crack it. I'd value some help. Thanks.
EDIT: I've added a screenshot of the list structure I'm trying to extract. The actual JSON object is quite large for a dput() output. Hope this helps
So, to get the date in this list, I'd use something like dat_raw$data$`1`[[1]]$date$gregorian$date.
What I'm trying to do is run a loop to extract multiple items of the list by cycling through $data$`1`[[1]]$..., $data$`2`[[1]]$... ... $data$`12`[[1]]$... using $data$m[[1]]$... in a for loop where m is the month.
Instead of dat_raw$`12`[[31]], you can have dat_raw[[12]][[31]] if 12 is the 12th element of the JSON. So your for loop would be:
for (m in 1:12) {
print(dat_raw[[m]][[31]])
}
This question already has answers here:
Calculate the mean of one column from several CSV files
(2 answers)
Closed 4 years ago.
I have CSV files named "001", "002",..."100" stored in the working directory. I need to write a function to read any of these files. I tried the function below, but it doesn't work.
func = function(ID)
{
inp = read.csv("ID.csv")
}
I think this is because "ID.csv" is a character whereas ID is a numeric variable, but I am not sure. Can someone please explain the reason and suggest the right code?
Sounds like you sort of understand the problem. "ID.csv" is a string literal and it is literally looking for a file named ID.csv. If I were you, I would input ID as a string like you have it (i.e. "001" instead of 1). Then try this:
func = function(ID)
{
inp = read.csv(paste(ID,".csv",sep=""))
}
This question already has an answer here:
Verify object existence inside a function in R [duplicate]
(1 answer)
Closed 5 years ago.
I am trying to add rows to a data frame if it exists, or assign it to initial data frame in case it doesn't exists. I have tried exists(), missing(), etc, but nothing is working for me.
exists(data) && is.data.frame(get(data))
Error in exists(data) : object 'data' not found
Any help would be highly appreciated.
I am trying to do something like
if(exists(data))
data <- rbind(data,new_data)
else
data <- new_data
If you read the documentation you’ll see that it says that exists requires
a variable name (given as a character string).
In other words, write:
exists('data') && is.data.frame(get('data'))
This question already has answers here:
How to name variables on the fly?
(6 answers)
r - how to use a variable in a variable
(3 answers)
Closed 9 years ago.
I have a function that uses readline to allow the user to enter the name they want to give for a variable I will be creating for them. Let's call this "USER.DEFINED.VARIABLE". It contains the name I want to use for another variable. Let's say that "USER.DEFINED.VARIABLE" gets set by readline to be "jimsfilename".
I know I can assign value to a variable named "jimsfilename" using:
assign(USER.DEFINED.VARIABLE,c(1,2,3,4,5))
"jimsfilename" will now have 1,2,3,4,5 in it. However, how do I now fuss with "jimsfilename", given that I don't (before readline assigns it to USER.DEFINED.VARIABLE) know what its name is?
In other words, lets say I now want to add 1 to every value in jimsfilename. I can't do:
USER.DEFINED.VARIABLE <- USER.DEFINED.VARIABLE + 1 # can't do this
because "USER.DEFINED.VARIABLE" is actually a text string name. I want instead to refer to jimsfilename, but all I have is USER.DEFINED.VARIABLE to indicate it. I'm sure this is something easy...
It depends bit on what you want to do, but here's an example of using get function:
x = 1
get("x") + 1
2
assign("name", get("x") + 1)
name
2
Why not just do all the manipulation of the variable (adding 1 or other changes) to a local copy of the variable with your own name, then at the end of the function/script/whatever do the assigning or other saving? That would be much simpler than creating the variable then having to use get to get a copy, change it, and assign it again.
Even better is to use your own variable name inside of a function, then just return the result and let the user decide what to name it at that point. This is the much more Rish way of doing things, it is best to not use the assign function at all. Most things that can be done using assign can be done much simpler by using a list and subscripting.
Functions should not change anything in the global environment, just return any values that the user might need and let the user make the assignment.
You can use eval and parse. The later interprets text as if it was an input in the console. The first evaluates the expression (generated by parse, for instance). Example:
> varname <- "user.defined.variable"
> varvalue <- 42
> eval(parse(text=paste(varname, varvalue, sep=" <- ")), envir=.GlobalEnv)
> ls()
[1] "user.defined.variable" "varname" "varvalue"
> user.defined.variable
[1] 42
Note that I've choosen the global environment as the destination for the new variable. You can make the appropriate changes if that is not the case.
To refer to the new variable later, you can use as.symbol. Just evaluate it under the environment where you assigned the new variable:
> eval(as.symbol(varname), envir=.GlobalEnv)
[1] 42
You can also use substitute to create expressions that eval can understand:
> eval(substitute(x+1, list(x=as.symbol(varname))), envir=.GlobalEnv)
[1] 43
To make changes to the new variable, just creat assignments expressions and evaluate them:
> eval(substitute(x <- x*10, list(x=as.symbol(varname))), envir=.GlobalEnv)
> eval(as.symbol(varname), envir=.GlobalEnv)
[1] 420