John Zach
John Zach

Reputation: 35

Why doesn't this R function work?

I created the following function to append new strings on a vector of strings called "meals". However, when I use this function to append an string input into my "meals" vector, it does not work.

 add <- function(str) {
      meals <- append(meals, as.character(str))  
    }

Upvotes: 1

Views: 8347

Answers (3)

Mark Peterson
Mark Peterson

Reputation: 9560

The issue here is variable scoping. The variable meals exists in your global environment where you are using it. When you run your function, there is no meals variable inside the function environment, so it inherits that variable from the global environment. However, when it modifies the variable, it creates a new version inside the function environment. The function can then use that modified version, but it never changes the meals variable from the global environment.

So, you can use the function as it is currently written, and just save the result to meals like so:

meals <- add("Steak")

The value is returned invisibly when you save it to a variable at the end of your function, but it does still output (like the full result of lm or hist that are only accessible if you save them to a new variable). This is one reason why it is a good idea to get in the habit of always ending functions with an explicit return or invisible statement.

My guess is that you are coming from a different programming language where changing a global variable inside a function changes the variable globally. That behavior by explicitly telling R to override that environmental behavior with <<-, which assigns the value outside of the current environment (instead of just within it). For example, this:

add <- function(str) {
  meals <<- append(meals, as.character(str))  
}

meals <- "Steak"

add("Chicken")

meals

results in meals holding both "Steak" and "Chicken" -- the behavior you want. HOWEVER, this is generally a bad idea in R. There are times when this behavior is nice, but the fact that it is very different from how R generally operates leaves a lot of opportunity for mistakes to slip in. I use this occasionally to get past scoping issues (often when working in shiny and needing to change things for the whole session, rather than just the current user), but I try to avoid it if at all possible.

I would encourage you to, instead, just use the construction:

meals <- append(meals, str)

directly, rather than trying to wrap this in a custom function that works so differently than standard R approaches.

Upvotes: 3

TBSRounder
TBSRounder

Reputation: 348

You need to make sure you are assigning the function to output to a variable in your case try something like these (3 possible solutions):

## longest/redundant
add <- function(str) {
   meals <- append(meals, as.character(str))
   return(meals)
}

## alternative
add2 <- function(str) {
   meals <- append(meals, as.character(str))
}

## simplest
add3 <- function(str) {
   append(meals, as.character(str))
}

meals <- c("chx","beef","pork")
str1 <- c(1, 2, 3)

newVar <- add(str1)
print(newVar)
[1] "chx"  "beef" "pork" "1"    "2"    "3"  

newVar2 <- add2(str1)
print(newVar2)
[1] "chx"  "beef" "pork" "1"    "2"    "3"  

newVar3 <- add3(str1)
print(newVar3)
[1] "chx"  "beef" "pork" "1"    "2"    "3"  

You can also consider an easier solution:

c(meals, str1) which will return the same exact thing. append is typically only used if you need to use the after argument.

Upvotes: 1

Puddlebunk
Puddlebunk

Reputation: 493

How does it not work?

One thing to consider: The output of a function is the last line in the function. for example:

x.plus.3 <- function(x){
        s <- x+3
}
x.plus.3(2)
#  nothing is printed

This is a valid function but if ran will have no output because all the function does is store x+3 into the object s.

If however, I change it to :

 x.plus.3 <- function(x){
         s <- x+3
         s
 }
 x.plus.3(2)
[1] 5  # i get the result printed

So you need to add meals as the last line in your function in order to get it to make it outside the function.

Upvotes: 1

Related Questions