1

I've looked through the forums here and figure out that <<- assign a variable inside a function to a global variable (to be accessible outside the function).

I've done so below, but to no avail - any thoughts?

> Billeddata_import <- function(burl="C:\\Users\\mcantwell\\Desktop\\Projects\\M & V Analysis\\Final_Bills.csv"){
+         billeddata<-read.csv(burl,header=TRUE, sep=",",stringsAsFactors = FALSE) %>%
+             mutate(Usage=as.numeric(Usage)) %>%
+                 #Service.Begin.Date=as.Date(Service.Begin.Date,format='%m/%d/%Y'),
+                  #Service.End.Date=as.Date(Service.End.Date,format='%m/%d/%Y')) %>%
+        
+         filter(UOM=="Kw",
+                !is.na(Usage),
+                Service.Description %in% c("Demand","Demand On Peak", "Demand Off Peak", "Dmd Partial Pk")) %>%
+         group_by(Location..,Service.Begin.Date,Service.End.Date) %>%
+         summarise(monthly_peak=max(Usage))
+         out<<-billdata
+     }
> out
Error: object 'out' not found
> 

The object billdata is a data table that I cleaned up in Billeddata_import(), and I'm hoping to use it in later functions.

Running the function alone yields:

> Billeddata_import()
Error in Billeddata_import() : object 'billdata' not found

without the out<<-billdata line, Billeddata_import() runs fine.

M--
  • 25,431
  • 8
  • 61
  • 93

2 Answers2

3

NOTE: Using <<- is bad practice. You can read this thread to know more about this.

You need to run the function. Here, you just define it. Take one step further and run it before looking for out.

Since we do not have your data, look at the example below;

#This is an example:
myfun <- function(xdat=df) {
  billeddata <- xdat %>% select(-var3) %>% 
                        filter(var1=="treatment5")

  out<<-billeddata
  }

 myfun(df) #You need to run the function!!!
 out

#         var1    var2       value 
# 1 treatment5 group_2 0.005349631 
# 2 treatment5 group_2 0.005349631 
# 3 treatment5 group_1 0.005349631

Data:

df <- structure(list(var1 = structure(c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 
      3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L), .Label = c("treatment1", "treatment2", 
      "treatment3", "treatment4", "treatment5"), class = "factor"), 
      var2 = structure(c(1L, 1L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 
      2L, 2L, 1L, 1L, 1L), .Label = c("group_1", "group_2"), class = "factor"), 
      var3 = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 3L, 2L, 2L, 3L, 
      2L, 3L, 2L, 2L, 3L), .Label = c("C8.0", "C8.1", "C8.2"), class = "factor"), 
      value = c(0.010056478, 0.009382918, 0.003014983, 0.005349631, 
      0.005349631, 0.010056478, 0.009382918, 0.003014983, 0.005349631, 
      0.005349631, 0.010056478, 0.009382918, 0.003014983, 0.005349631, 
      0.005349631)), .Names = c("var1", "var2", "var3", "value"
  ), class = "data.frame", row.names = c(NA, -15L))

P.S.

Even if you want to use return(out) you still need to run the function after defining it.

Moreover, using return() will not add a variable to your global. You need to assign it while calling the function, like this:

out <- myfun(df)
M--
  • 25,431
  • 8
  • 61
  • 93
  • 4
    I think you need to be stronger in your answer about discouraging use of `<<-` here. It is bad practice and returning the value is the better way – dww Aug 15 '17 at 22:54
1

You can just use return(out) as the last line in your function, and then call your function every time you need to access your variable.

M--
  • 25,431
  • 8
  • 61
  • 93
sweetmusicality
  • 937
  • 1
  • 10
  • 27
  • @sweeI tried that and couldn't access the columns. –  Aug 15 '17 at 22:23
  • 1
    This is actually not necessary--you don't need to use the return function to return an object at the end of a function. The `return(out)` does the same thing as `out` except it also exits the function. – be_green Aug 15 '17 at 22:37