R has lexical scope; a variable that is not assigned in a function is resolved against its static environment. In your case, f1 sees the value of c in your global environment, which is 2. Within f2, c == 3 because it is passed as an argument which masks the global c, but when f1 is called, it still sees c==2 from its enclosing environment. You expected dynamic scoping, where c would take the value of its runtime environment (i.e., within f2). You can set c <- 3 outside the functions, before f2, or you can do this to copy the local value passed as 'c' in f2 to the global environment:

 f2 = function(a,b,c){
    c <<- c     # local argument c copied to global c
    f1(a,b)
 }

more discussion of lexical scope in R: https://darrenjw.wordpress.com/2011/11/23/lexical-scope-and-function-closures-in-r/

Answer from chaslewis on Stack Overflow
🌐
HBC Training
hbctraining.github.io › Intro-to-R › lessons › introR-nested-functions.html
Nested Functions | Introduction to R - ARCHIVED
May 9, 2017 - Nested code: Rather that assigning the output from each step to a separate variable, we could also just nest them into one another. To create a nested function, simply replace the variable name with the code on the right hand side of the assignment operator.
🌐
W3Schools
w3schools.com › r › r_functions_nested.asp
R Nested Functions
Nested_function <- function(x, y) { a <- x + y return(a) } Nested_function(Nested_function(2,2), Nested_function(3,3)) Try it Yourself » · The function tells x to add y. The first input Nested_function(2,2) is "x" of the main function.
🌐
Educative
educative.io › answers › how-can-we-create-a-nested-function-in-r
How can we create a nested function in R
Line 4: The function we created tells x to multiply y and assign the output to a variable a. Line 5: We return the value of a. Line 9: We make the first input myFunction(2,2) represent the primary function’s x parameter.
🌐
RPubs
rpubs.com › avbernat › 620393
RPubs - Lesson 11 - Nested Functions and Nested Scripts
Sign in Register · Lesson 11 - Nested Functions and Nested Scripts · by Anastasia Bernat · Last updated over 6 years ago · Hide Comments (–) Share Hide Toolbars ·
🌐
Pluralsight
pluralsight.com › blog › tech guides & tutorials
Creating Nested and Special-Purpose Functions in R | Pluralsight
January 17, 2020 - For example, if we want to visualize class separation by numeric features for our dataset, we can do that using a box plot. There are four numeric features in the data, namely Income, Loan_amount, Age, and Investment.
Top answer
1 of 1
5

R uses lexical scoping which means that if a function needs to reference an object not defined in that function it looks at the environment in which the function was defined, not the caller. In the question g is defined in the global environment so that is where g looks for c.

Also note that in R we would not call the functions in the question nested functions. Rather what is nested is the calls, not the functions. In (3) below we show nested functions.

1) We can reset a function's environment in which case it will think it was defined in that environment.

g <- function(a,b){       # help function
    a^2 + b^2 - c
}

f <- function(a,b,c,d){   # main function
    environment(g) <- environment()
    g(a,b)
}

f(1, 2, 3, 4)
## [1] 2

2) Another possibility is to explicitly tell it which environment to search using envir$c (where envir is the desired environment) or get("c", envir) or with(envir, c) . envir$c will look into envir. The other two will look there and if not found will look into ancestor environments. (Each environment has a parent or the emptyenv(). This is distinct from the call stack.)

g <- function(a, b, envir = parent.frame()){       # help function
    a^2 + b^2 - envir$c
}

f <- function(a,b,c,d){   # main function
    g(a,b)
}

f(1, 2, 3, 4)
## [1] 2

3) We can nest the functions so that g is defined in f.

f <- function(a,b,c,d){   # main function
    g <- function(a,b){       # help function
        a^2 + b^2 - c
    }
    g(a,b)
}

f(1, 2, 3, 4)
## [1] 2

4) Of course you could just pass c and avoid all these problems.

g <- function(a, b, c) { 
    a^2 + b^2 - c
}

f <- function(a, b, c, d) {   # main function
    g(a, b, c)
}

f(1, 2, 3, 4)
## [1] 2
🌐
Stats with R
statswithr.com › r-functions › the-nest-function-in-r
The “nest” Function in R - Stats with R
February 29, 2024 - # Load necessary packages ... single nested column 'data' result <- nest(data, data = c(ID, Value)) # Display the result print(result) In this example, the nest function from the tidyr package is used to reshape the sample data frame data by nesting the ‘ID’ and ...
Find elsewhere
🌐
ProgramsBuzz
programsbuzz.com › article › r-nested-functions
R: Nested Functions
October 20, 2021 - We use nested function to avoid complexity, rather than assigning values from each step to a separate variable we can easily nest them into one another.To create a nested function we can replace the variable name with the code on right hand side of assignment operator.
🌐
HowDev
how.dev › answers › how-can-we-create-a-nested-function-in-r
How can we create a nested function in R
Line 4: The function we created tells x to multiply y and assign the output to a variable a. Line 5: We return the value of a. Line 9: We make the first input myFunction(2,2) represent the primary function’s x parameter.
🌐
CRAN
cran.r-project.org › web › packages › flow › vignettes › nested-functions.html
Explore Nested Functions
Many times a function will contain another function definition, these will not always be very readable in the body of the main function. {flow} offers a way to visualize those. When using flow on the main function, a message will signify what nested functions can be viewed. The base function bquote is a good example.
🌐
Educative
educative.io › home › courses › learn r › nested functions
Nested Functions
How cool is that! functionName1 <- function(argument1, argument2, ..., argumentN) { # Creating a Function Inside a Function functionName2 <- function(argument1, argument2, ..., argumentN) { # Statements } # Using the created function ...
🌐
RDocumentation
rdocumentation.org › packages › tidyr › versions › 0.8.3 › topics › nest
nest function - RDocumentation
For instance, c(x, !! x) selects the x column within the data frame and the column referred to by the object x defined in the context (which can contain either a column name as string or a column position). ... # NOT RUN { library(dplyr) as_tibble(iris) %>% nest(-Species) as_tibble(chickwts) ...
🌐
R-bloggers
r-bloggers.com › r bloggers › nesting functions in r with the piping operator
Nesting Functions in R with the Piping Operator | R-bloggers
November 29, 2016 - None of these subsets give us the complete information to answer our question. All we need is the final result–ed_exp4. So, is there a way to get to ed_exp4 without creating the first three objects. Yes, there is–but it’s a little tricky… · ### Create final result using a single nested function ed_exp5 <- arrange(mutate(select(filter(education, Region == 2),c(State,Minor.Population, Education.Expenditures)), Expenditures.Per.Child = Education.Expenditures / Minor.Population),desc(Expenditures.Per.Child))
🌐
Sarthaks eConnect
sarthaks.com › 3520713 › r-nested-functions
R Nested Functions - Sarthaks eConnect | Largest Online Education Community
June 14, 2023 - Discover the power of R nested functions with our comprehensive guide! Learn how to leverage this ... resource - dive into R nested functions now!
🌐
RDocumentation
rdocumentation.org › packages › MuMIn › versions › 1.43.17 › topics › nested
nested function - RDocumentation
nested(x, indices = c("none", "numeric", "rownames"), rank = NULL) ... if omitted or "none" then the function checks if, for each model, there are any higher ranked models nested within it. If "numeric" or "rownames", indices or names of all nested models are returned.
🌐
Bookdown
bookdown.org › Maxine › r4ds › nesting.html
6.3 Nesting | R for data science: tidyverse and beyond
Now gapminder_nest is a tibble with 142 rows representing 142 countries with their respective time series data from 1952 - 2007 stored in the list column data. Then we can combine mutate() and map to create a new column to fit a linear model for each country: mod_fit <- function(data) { lm(lifeExp ~ year1950, data = data) } gapminder_model <- gapminder_nest %>% mutate(model = map(data, mod_fit)) #> mutate: new variable 'model' with 142 unique values and 0% NA gapminder_model #> # A tibble: 142 x 4 #> continent country data model #> <fct> <fct> <list> <list> #> 1 Africa Algeria <tibble [12 x 5]> <lm> #> 2 Africa Angola <tibble [12 x 5]> <lm> #> 3 Africa Benin <tibble [12 x 5]> <lm> #> 4 Africa Botswana <tibble [12 x 5]> <lm> #> 5 Africa Burkina Faso <tibble [12 x 5]> <lm> #> 6 Africa Burundi <tibble [12 x 5]> <lm> #> # ...
🌐
Programiz
programiz.com › r › function
R Functions (with Examples)
First, add(1, 2) and add(3, 4) are computed and the results are passed as arguments to the outer add() function. Hence, the result is the sum of all four numbers. Let's create a nested function by writing a function inside another function.