I'm working on a function and need to know how to reference the incoming parameters.
For example, in python or lots of other languages, you can reference the input parameters something like this:
sys.argv[1:].
How can I reference the name of a parameter in R?
The specific problem I'm trying to solve is I want to capture the string value of the incoming parameter, so I can paste it as a concentration with a list of column_names I want to iterate through.
Here's the head of the function call, just so you can see the incoming parameter:
function(df_in)
So here's an example of the code I am writing and I want the string value of the dataframe_in, not the object that it references.
col_name <-paste(df_in,varnames[i],sep="$")
if df_in contained "my_df" and the current column_name is my_col, I'm trying to have col_name in the example above set to my_df$my_col.
I was thinking of using the get() function but quite sure how to apply it in this situation.
Thanks
Try something along these lines:
fn1 <- function(df_in){ in_nam <- deparse(substitute(df_in) )
col_names <-paste(in_nam, names(df_in), sep="$")
cat(col_names) }
> dfrm <- data.frame(a=1:10, b=letters[1:10])
> fn1(dfrm)
#dfrm$a dfrm$b
You didn't say what varnames was supposed to be so I'm guessing you want the column names from the object. BTW, don't expect to be able to reference the column values with those character values. They are no longer language objects.
Related
I have a loop which is running over a vector containing names of a few tens of dataframes that are in my environment. On each iteration, I want to access the dataframe using the name, and access a specific column within it. As I understand it, the best way to access a variable with a string is using get().
But when I try and do this (with name being a variable containing the string "first.name"):
get(column.name, name)
I get the error:
Error in as.environment(pos) : no item called "first.name" on the search list
It does work if I try to run:
get(column.name, first.name)
So, assuming that get() is the right function for this, what am I doing wrong?
Reproduceable example:
my.df <- as.data.frame(x = seq(1:10), y = rnorm(10))
name <- "my.df"
get("x",name)
We may need to use
get(name)[[column.name]]
I have the below function which inserts a row into a table (new_scores) based upon the attribute that I feed into it (where the attribute represents a table that I select things from):
buildNewScore <- function(x) {
something <- bind_rows(new_scores,x%>%select(ATT,ADJLOGSCORE))
return(something)
}
Which works fine when I define x.
But when I try to create a for loop that feeds the rest of my attributes into the function it falls over as I'm feeding in a character.
attlist <- c('Z','Y','X','W','V','U','T','RT','RO')
record_count <- length(attlist)
for (x in c(1:record_count)){
buildNewScore(attlist[x])
}
I've tried to convert the attribute into other classes but I can't get the loop to use anything I change it to (name, data.frame etc.).
Anyone have any ideas as to where I'm going wrong - is my attlist vector in the wrong format?
Thanks,
Spikelete.
I have stored a list of names as characters and want to convert them to something that can be accepted as data frame name. something like this:
for (i in 1:18) {
str[i] <- paste("alert_month_amount_",i,sep="")
}
name_str = as.character(str)
then name_str will be:
name_str[1] would be "alert_month_amount_1"
now i want to assign certain data to a data frame that uses name_str[i] inside a loop like:
for (n in 1:18){
name_str[n] <- subset(by_Month_Acct_Num,month==month_index[n] & year==year_index[n])
}
but this does not work perhaps because the names are passed as characters inside double quotation mark ("). I would appreciate your help.
You can use assign for this:
assign(name_str[n], subset(by_Month_Acct_Num,month==month_index[n] & year==year_index[n]))
This is FAQ 7.21. The most important part of that answer is the end where it says (like #MrFlick) that it is better to use a list. You really should learn how to take advantage of R's vectorized functions.
The paste and paste0 functions are both vectorized, so your first bit of code can be replaced with:
name_str <- paste0("alert_month_amount_", 1:18)
without need for the loop.
You could create your list and fill it with code like:
alert_month_amount <- list()
for(i in 1:18) {
alert_month_amount[[i]] <- subset(by_Month_Acct_Num,month==month_index[n] & year==year_index[n])
}
Or possibly even easier using the split function. You could also use lapply or mapply.
If you want the elements named then just do:
names(alert_month_amount) <- name_str
Now with everything in a single list you can copy, save, delete, etc. one object rather than needing another loop to do each individual piece. If you want to do the same thing (calculate a summary, fit a regression, etc.) on each piece created then with everything in a list you can just use lapply or sapply on the list rather than having to create another loop and figuring out how to grab each piece in the loop and save it to an output object.
Am R newb. I coded a function that uses 3 parameters. In my code i use one of the parameters to help me read files from a directory. There are 100 files in the directory. The code works fine when I pass it all the function parameters and specify the files i want to read.
functionX(var1, var2, id) and functionX(var1, var2, id = 1:100)
## Below is the first line of code for me that uses "id".
sub.file.names <- file.names[id] ### Get file names
The odd thing is that when a value for "id" is not passed to the function initially (or set with a 1:100 default), the code seems to read all the file names anyway. And it does so even though a value for "id" has never been established.
It's as if R somehow treats the two functions below the same when the user omits passing a value to "id" when executing the function ... eg, functionx("var1", "var2") ## and does not pass any id variable
functionx(var1, var2, id)
functionx(var1, var2, id = 1:100)
Any pointers on why this is happening would be great to know. I feel the answer is obvious, but have not been able to figure it out.
Let me try to explain what is happening with a simple example. Consider the following function
foo = function(i){
LETTERS[i]
}
When you try foo(), you will notice that the function returns all 26 uppercase letters. Why does that happen? Well, everything in R is a function. So when you say LETTERS[i], you are essentially calling the function [. So, the function call is
`[`(LETTERS, i)
Since i is missing, this call is executed as [(LETTERS) (essentially LETTERS[]) which returns all elements of the vector. Note that this occurs because the [ function allows for the i argument to be missing while calling it. Check ?[
If you want the function to act differently when id is missing, either check for missing(id), or explicitly set it to NULL as default. So, if you do
foo2 = function(i = NULL){
LETTERS[i]
}
foo2() will return a zero length character vector.
Say that I have the following function:
myfun <- function(x){
assignee <- get_assignee_name()
message(paste0("output assigned to ",assignee,"!"))
x
}
my_var <- myfun(7)
output assigned to my_var!
I am looking for something that does the job of get_assignee_name() above.
It should be a function or a few lines of code that is called from inside a function, it examines the call that it occurs inside of and returns the object that is being assigned to as a character, if one exists. So in the example
answer <- myfun(10)
the message "output assigned to answer!" should appear.
I am aware that this seems unnecessarily complicated, but it is just an example to demonstrate the point for a more complicated use case. I am also aware that of ways around this involving passing the variable name into the function as a parameter and then calling assign. This won't solve the problem in this case, where this should be transparent to the user
This is not possible because <- is a primitive and quite special function. It is not part of the call stack. You would need to use assign instead:
myfun <- function(x){
assignee <- sys.call(1)
if (assignee[[1]] == quote(assign))
message(paste0("output assigned to ",assignee[[2]],"!"))
x
}
assign("my_var", myfun(7))
#output assigned to my_var!
my_var
#[1] 7
However, I suggest you reconsider how you approach your actual issue.