Reputation: 35
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
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
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
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