How to Make Object Created Within Function Usable Outside

Make an object accessible outside a function in R

The best solution for you would be to refactor your current function, possibly into smaller functions, in such a way that you can easily get the value of marginal separately. Then, use it to complete your current calculation.

That being said, if you want a quick fix you could resort to using the parent scope assignment operator <<-, e.g.

marginal <- NULL

p <- function(t, N1, N2=NULL, delta) {
efN = ifelse(is.null(N2), N1, N1*N2/(N1+N2))
df = ifelse(is.null(N2), N1 - 1, N1 + N2 - 2)

prior <- function(delta) dnorm(delta, 0, 1)
likelihood <- function(delta) dt(t, df, delta*sqrt(efN) )

# note the assignment being done here carefully
marginal <<- integrate(function(x) prior(x)*likelihood(x), -Inf, Inf)[[1]]

post <- function(x) prior(x)*likelihood(x) / marginal

return(post(delta))
}

# now marginal contain the value assigned in the function call above

However, it is usually not recommended to take such an approach. I only offer it as a quick fix, with the strong suggestion that you rethink your code design.

Trying to open objects created within a function outside it in R Studio

Update: I now should have solved your problem using the ensym() and assign functions.

Essentially we want to access the global variable with the name passed to the function. In order to do this we capture its name not its contents with ensym and then we assign it using the assign function which we tell that the object we are looking for is in the global environment and has the name that we stored with ensym.

Here is a brief explanation showing how it works.

library(rlang)

f <- function(x) {
x <- ensym(x)
assign(as_string(x), 2, envir = globalenv())
}

john <- 1

f(john)

print(john)
#> [1] 2

Created on 2021-04-05 by the reprex package (v2.0.0)

For your function we would want to take this approach:

library(rlang)

tuits <- function(x, y) {
# Get the name of the variable we want to store
x <- ensym(x)
tmp <- search_tweets(y, n=5000, include_rts = FALSE, lang = "es",
since = since, until = until) %>%
filter(screen_name != y)

# Assign the value to the variable in the global environment
assign(as_string(x), tmp, envir = globalenv())
}

tuits(Juan, "JuanPerez")

# to test
print(Juan)

Old Answer (improved on in the above section)
I believe the issue here is an issue of understanding scope or environments. If an object is modifed or set within the environment used by a function or the sdcope of the function then it can only be accessed in that form within the function.

Usually the scope of a function contains the variables that are assigned inside the function statement.

Usually the way to solve this would be to return the object using return(x) and setting the function call to the object.

tuits <- function(x, y) {
x <- search_tweets(y, n=5000, include_rts = FALSE, lang = "es",
since = since, until = until) %>%
filter(screen_name != y)
return(x)
}

Juan <- tuits(Juan, "JuanPerez")

You could modify the object x using a superassignment (<<-) operation however this is usually not best practise. I will provide this solution for completeness sake.

Superassignment modifies the variable in the global scope. This however will assign the value to x not the object.

tuits <- function(x, y) {
x <<- search_tweets(y, n=5000, include_rts = FALSE, lang = "es",
since = since, until = until) %>%
filter(screen_name != y)
}

tuits(Juan, "JuanPerez")

Javascript - calling an external function as a property of an object

You can add that property to the object when you are iterating over it.

const arrayObj = [{
number1: 1,
number2: 2,
}];

function sum(n1, n2) {
return n1 + n2;
}

for (let i in arrayObj){
arrayObj[i].sum = sum(arrayObj[i].number1, arrayObj[i].number2)
console.log(arrayObj[i])
}

Access a function variable outside the function without using global

You could do something along these lines (which worked in both Python v2.7.17 and v3.8.1 when I tested it/them):

def hi():
# other code...
hi.bye = 42 # Create function attribute.
sigh = 10

hi()
print(hi.bye) # -> 42

Functions are objects in Python and can have arbitrary attributes assigned to them.

If you're going to be doing this kind of thing often, you could implement something more generic by creating a function decorator that adds a this argument to each call to the decorated function.

This additional argument will give functions a way to reference themselves without needing to explicitly embed (hardcode) their name into the rest of the definition and is similar to the instance argument that class methods automatically receive as their first argument which is usually named self — I picked something different to avoid confusion, but like the self argument, it can be named whatever you wish.

Here's an example of that approach:

def add_this_arg(func):
def wrapped(*args, **kwargs):
return func(wrapped, *args, **kwargs)
return wrapped

@add_this_arg
def hi(this, that):
# other code...
this.bye = 2 * that # Create function attribute.
sigh = 10

hi(21)
print(hi.bye) # -> 42

Note

This doesn't work for class methods. Just use the instance argument, named self by convention, that's already passed to methods instead of the method's name. You can reference class-level attributes through type(self). See Function's attributes when in a class.

Assign multiple objects to .GlobalEnv from within a function

Update of 2018-10-10:

The most succinct way to carry out this specific task is to use list2env() like so:

## Create an example list of five data.frames
df <- data.frame(x = rnorm(25),
g = rep(factor(LETTERS[1:5]), 5))
LIST <- split(df, df$g)

## Assign them to the global environment
list2env(LIST, envir = .GlobalEnv)

## Check that it worked
ls()
## [1] "A" "B" "C" "D" "df" "E" "LIST"

Original answer, demonstrating use of assign()

You're right that assign() is the right tool for the job. Its envir argument gives you precise control over where assignment takes place -- control that is not available with either <- or <<-.

So, for example, to assign the value of X to an object named NAME in the the global environment, you would do:

assign("NAME", X, envir = .GlobalEnv)

In your case:

df <- data.frame(x = rnorm(25),
g = rep(factor(LETTERS[1:5]), 5))
LIST <- split(df, df$g)
NAMES <- c("V", "W", "X", "Y", "Z")

lapply(seq_along(LIST),
function(x) {
assign(NAMES[x], LIST[[x]], envir=.GlobalEnv)
}
)

ls()
[1] "df" "LIST" "NAMES" "V" "W" "X" "Y" "Z"

R: Name an object created within a function with a name defined by the function

Try this,

simulate <- function(scenario="xxx"){

simdat <- replicate(4, rnorm(10), simplify=FALSE)
data_name <- paste("simdat", scenario, sep=".")
assign(data_name, simdat)
save(list = data_name, file = paste0("simdat_", scenario, ".Rdata"))
}


Related Topics



Leave a reply



Submit