Tare Suriel
Tare Suriel

Reputation: 21

Parameterize name of output dataframe in global environment, assigned to from a function

Trying to pass into a function what I want it to name the dataframe it creates, then save it to global environment.

I am trying to automate creating dataframes that are subsets of other dataframes by filtering for a value; since I'm creating 43 of these, I'm writing a function that can automatically:

I can do a) fine but am having trouble with b).

Say I have a dataset which includes a column named "Team" (detailing whose team that member belongs to):

original.df <- read_csv("../original_data_set")

I create a function to split that dataset according to values in one of its columns...

split.function <- function(string){
    x <- original.df
    as.name(string) <<- filter(x, str_detect(`Team`, string))
}

... then save the dataframe with the name:

split.by.candidate('Team.Curt')

I keep getting:

> Error in as.name(x) <<- filter(y, str_detect(`Receiving Committee`, x)) : 
  object 'x' not found

But I just want to see Team.Curt saved as a data.frame in my global environment when I do this with rows including the term Team.Curt

Upvotes: 1

Views: 574

Answers (2)

smci
smci

Reputation: 33940

Both <- and <<- assignments require that the statement hardcodes the object name. Since you want to parameterize the name, as in your cases, you must use assign().

<<- is merely a variant of <- that can be used inside a function, and does a bottom-up search of environments until it either reaches the top (.GlobalEnv) or finds an existing object of that name. In your case that's unnecessary and slightly dangerous, since if an object of that name existed in some environment halfway up the hierarchy, you'd pick it up and assign to it instead.

So just use assign(..., envir = .GlobalEnv) instead.

But both <<- or assigning directly into .GlobalEnv within functions are strongly discouraged as being disasters in waiting, or "life by a volcano" (burns-stat.com/pages/Tutor/R_inferno.pdf). See the caveats at Assign multiple objects to .GlobalEnv from within a function. tidyverse is probably a better approach for managing multiple dataframes.

Upvotes: 0

Sven Hohenstein
Sven Hohenstein

Reputation: 81683

You can use assign to create objects based on a string:

split.function <- function(string){
   x <- original.df
   assign(string, filter(x, str_detect(`Team`, string)), envir = .GlobalEnv)
}

Here, envir = .GlobalEnv is used to assign the value to the global environment.

Upvotes: 1

Related Questions