How to make object created within function usable outside

56,540

Solution 1

That's easy: use <<- for assignment to a global.

But then again, global assignment is evil and not functional. Maybe you'd rather return a list with several results from your function? Looking at your code, it seems that your second function may confuse the return and print. Make sure you return the correct data structure.

Solution 2

A little about functional programming. First of all, when you define your function:

getTitles <- function(pages) {
  [...]
  return(my.matrix)
  print(my.matrix)
}

know that when the function is called it will never reach the print statement. Instead, it will exit right before, with return. So you can remove that print statement, it is useless.

Now the more important stuff. Inside your function, you define and return my.matrix. The object only exists within the scope of the function: as the function exits, what is returned is an unnamed object (and my.matrix is lost.)

In your session, when you call

getTitles(mypages)

the result is printed because you did not assign it. Instead, you should do:

out.matrix <- getTitles(mypages)

Now the result won't be printed but you can definitely do so by typing print(out.matrix) or just out.matrix on a single line. And because you have stored the result in an object, you can now reuse it for further manipulations.

If it help you grasp the concept, this is all the same as calling the c() function from the command line:

c(1, 5, 2)      # will return and print a vector 
x <- c(1, 5, 2) # will return and assign a vector (not printed.)

Bonus: Really, I don't think you need to define getTitles, but you can use one of the *apply functions. I would try this:

url    <- as.character(mypages)
title  <- sapply(url, getTitle)
report <- data.frame(url, title)
write.csv(report, file = "report.csv", row.names = FALSE)

Solution 3

Can't you just use <<- to assign it the object to the workspace? The following code works for me and saves the amort_value object.

amortization <- function(cost, downpayment, interest, term) {
  amort_value <<- (cost)*(1-downpayment/100)*(interest/1200)*((1+interest/1200)^(term*12))/((1+interest/1200)^(term*12)-1)
  sprintf("$%.2f", amort_value)         

}
amortization(445000,20,3,15)
amort_value

Solution 4

At the end of the function, you can return the result.

First define the function:

getRangeOf <- function (v) {
    numRange <- max(v) - min(v)
    return(numRange)
}

Then call it and assign the output to a variable:

scores <- c(60, 65, 70, 92, 99)
scoreRange <- getRangeOf(scores)

From here on use scoreRange in the environment. Any variables or nested functions within your defined function is not accessible to the outside, unless of course, you use <<- to assign a global variable. So in this example, you can't see what numRange is from the outside unless you make it global.

Usually, try to avoid global variables at an early stage. Variables are "encapsulated" so we know which one is used within the current context ("environment"). Global variables are harder to tame.

Share:
56,540
Sergey Samusev
Author by

Sergey Samusev

Updated on July 17, 2022

Comments

  • Sergey Samusev
    Sergey Samusev almost 2 years

    I created a function which produces a matrix as a result, but I can't figure out how to make the output of this function usable outside of the function environment, so that I could for instance save it in csv file.

    My code for function is the following:

    created function which takes url's from specific site and returns page title:

    getTitle <- function(url) {
      webpage <- readLines(url)
      first.row <- webpage[1]
      start <- regexpr("<title>", first.row)
      end <- regexpr("</title>", first.row)
      title <- substr(first.row,start+7,end-1)
      return(title)
    }
    

    created function which takes vector of urls and returns n*2 matrix with urls and page titles:

    getTitles <- function(pages) {
      my.matrix <- matrix(NA, ncol=2, nrow=nrow(pages))
      for (i in seq_along(1:nrow(pages))) {
        my.matrix[i,1] <- as.character(pages[i,])
        my.matrix[i,2] <- getTitle(as.character(pages[i,])) }
      return(my.matrix)
      print(my.matrix)}
    

    After running this functions on a sample file from here http://goo.gl/D9lLZ which I import with read.csv function and name "mypages" I get the following output:

    getTitles(mypages)
         [,1]                                               [,2]                                                
    [1,] "http://support.google.com/adwords/answer/1704395" "Create your first ad campaign - AdWords Help"      
    [2,] "http://support.google.com/adwords/answer/1704424" "How costs are calculated in AdWords - AdWords Help"
    [3,] "http://support.google.com/adwords/answer/2375470" "Organizing your account for success - AdWords Help"
    

    This is exactly what I need, but I'd love to be able to export this output to csv file or reuse for further manipulations. However, when I try to print(my.matrix), I am getting an error saying "Error: object 'my.matrix' not found"

    I feel like it's quite basic gap in my knowledge, but have not been working with R for a while and could not solve that.

    Thanks! Sergey