Environments

Mini-Lecture 10

Ben Baumer

Smith College

2024-10-17

Environments

Types of environments

What I want you to focus on:

  • 7.4.1: Package environments
  • 7.4.3: Namespace environments

Less important right now:

  • 7.2.4: Super assignment
  • 7.3: Recursing over environments
  • 7.5: Call stacks
  • 7.6: Environments as data structures

7.4: Special Environments

  • Package environments: objects provided by the package
library(rlang)
pkg_env("stats")
<environment: package:stats>
attr(,"name")
[1] "package:stats"
attr(,"path")
[1] "/opt/R/4.4.2/lib/R/library/stats"
  • Execution environments: where the function is executed
  • Namespace environments: what is available to the function
ns_env(stats::sd)
<environment: namespace:stats>
  • Function environments: where the function is defined
fn_env(stats::sd)
<environment: namespace:stats>

Package environment for stats

pkg_env("stats") |>
  env_names()
  [1] "asOneSidedFormula"    "r2dtable"             "drop.terms"          
  [4] "confint.lm"           "is.mts"               "nlminb"              
  [7] "alias"                "gaussian"             "profile"             
 [10] "ls.diag"              "mahalanobis"          "rmultinom"           
 [13] "dpois"                "numericDeriv"         "makepredictcall"     
 [16] "qlogis"               "loadings"             "dlogis"              
 [19] "nlm"                  "residuals.glm"        "qcauchy"             
 [22] "nextn"                "nls"                  "plot.stepfun"        
 [25] "arima0.diag"          "dummy.coef"           "ftable"              
 [28] "as.formula"           "pairwise.wilcox.test" "time"                
 [31] "embed"                "mantelhaen.test"      "dwilcox"             
 [34] "ar"                   "oneway.test"          "fligner.test"        
 [37] "bw.bcv"               "rWishart"             "predict.glm"         
 [40] "logLik"               "confint.default"      "AIC"                 
 [43] "rlogis"               "bw.ucv"               "arima"               
 [46] "plot.ts"              "tsp"                  "model.extract"       
 [49] "tsp<-"                "stat.anova"           "update.formula"      
 [52] "qbeta"                "bw.SJ"                "factanal"            
 [55] "drop.scope"           "summary.aov"          "optimHess"           
 [58] ".lm.fit"              "cooks.distance"       "dnorm"               
 [61] "psmirnov"             "extractAIC"           "qbirthday"           
 [64] "C"                    "sortedXyData"         "D"                   
 [67] "lowess"               "varimax"              "optimize"            
 [70] "manova"               "deviance"             "optim"               
 [73] "lag.plot"             "constrOptim"          "splinefunH"          
 [76] "reformulate"          "pacf"                 "mcnemar.test"        
 [79] "df"                   "tsSmooth"             "make.link"           
 [82] "glm.control"          "hasTsp"               "pgamma"              
 [85] "addmargins"           "dexp"                 "power.anova.test"    
 [88] "prop.test"            "model.weights"        "ave"                 
 [91] "is.stepfun"           "heatmap"              "stepfun"             
 [94] "loess.smooth"         "window<-"             "line"                
 [97] "qqline"               "ar.mle"               "residuals"           
[100] "lsfit"                "get_all_vars"         "dt"                  
[103] "splinefun"            "ks.test"              "cor"                 
[106] "add.scope"            "ecdf"                 "pwilcox"             
[109] "cov"                  "dendrapply"           "rsignrank"           
[112] "bandwidth.kernel"     "as.dist"              "SSweibull"           
[115] "bw.nrd"               "start"                "plnorm"              
[118] "ts.union"             "mvfft"                "dweibull"            
[121] "as.ts"                "cor.test"             ".checkMFClasses"     
[124] "effects"              "reorder"              "KalmanForecast"      
[127] "eff.aovlist"          "qgamma"               "glm.fit"             
[130] "dgamma"               "plot.spec.coherency"  "cov2cor"             
[133] "ls.print"             "setNames"             "acf2AR"              
[136] "add1"                 "rcauchy"              "shapiro.test"        
[139] "deriv3"               "window"               "model.tables"        
[142] "model.matrix"         ".nknots.smspl"        "KalmanLike"          
[145] "SSasymp"              "predict"              "as.stepfun"          
[148] "power.prop.test"      "t.test"               "rstandard"           
[151] "binom.test"           "cophenetic"           "pbeta"               
[154] "KalmanRun"            "naprint"              "qlnorm"              
[157] "plclust"              "model.response"       "dlnorm"              
[160] "lag"                  "spec.pgram"           "interaction.plot"    
[163] "fitted"               "rgeom"                "estVar"              
[166] "rgamma"               "arima0"               "loglin"              
[169] "ar.yw"                "promax"               "phyper"              
[172] "drop1"                "SSfol"                "runif"               
[175] "family"               "quantile"             "wilcox.test"         
[178] "psignrank"            "complete.cases"       "offset"              
[181] "scatter.smooth"       "dmultinom"            "rlnorm"              
[184] "approx"               "naresid"              "SSfpl"               
[187] "proj"                 "supsmu"               "qqnorm"              
[190] "end"                  "printCoefmat"         "princomp"            
[193] "dnbinom"              "lm.influence"         "aggregate.data.frame"
[196] "rect.hclust"          "convolve"             "ansari.test"         
[199] "median.default"       "ARMAacf"              "poly"                
[202] "NLSstRtAsymptote"     "power.t.test"         "write.ftable"        
[205] "qhyper"               "polym"                "weights"             
[208] "dhyper"               "contrasts<-"          "kernel"              
[211] "friedman.test"        "acf"                  "qwilcox"             
[214] "filter"               "lm.fit"               "rpois"               
[217] "cmdscale"             "factor.scope"         "Gamma"               
[220] "pweibull"             "pchisq"               "ksmooth"             
[223] "symnum"               "smooth"               "quasipoisson"        
[226] "ppr"                  "spec.ar"              "pnbinom"             
[229] "coefficients"         "model.offset"         "dbeta"               
[232] "SSasympOff"           "pbirthday"            "replications"        
[235] "ar.ols"               "rhyper"               "spectrum"            
[238] "lm"                   "expand.model.frame"   "kernapply"           
[241] "bw.nrd0"              "stl"                  "loess"               
[244] "IQR"                  "qgeom"                "contr.helmert"       
[247] "na.pass"              "toeplitz"             "pairwise.t.test"     
[250] "dist"                 ".getXlevels"          "NLSstClosestX"       
[253] "getInitial"           "sigma"                "qchisq"              
[256] "contr.poly"           "dchisq"               "spline"              
[259] "qunif"                "confint"              "pairwise.table"      
[262] "SSasympOrig"          "pexp"                 "plot.spec.phase"     
[265] "medpolish"            "density.default"      "ptukey"              
[268] "cancor"               "Box.test"             "TukeyHSD"            
[271] "rnorm"                "poisson"              "var.test"            
[274] "bartlett.test"        "na.fail"              "summary.stepfun"     
[277] "model.frame"          "covratio"             "contrasts"           
[280] "ar.burg"              "residuals.lm"         "df.residual"         
[283] "ts.intersect"         "power"                "SSlogis"             
[286] "glm"                  "rchisq"               "getCall"             
[289] "chisq.test"           "model.matrix.lm"      "coef"                
[292] "step"                 "ppoints"              "vcov"                
[295] ".preformat.ts"        "qqplot"               "DF2formula"          
[298] "update.default"       "qtukey"               "qpois"               
[301] "quade.test"           "df.kernel"            "influence"           
[304] "qsmirnov"             "cutree"               "pf"                  
[307] "poisson.test"         "case.names"           "frequency"           
[310] "tsdiag"               "qweibull"             "NLSstLfAsymptote"    
[313] "kmeans"               "weighted.residuals"   "mauchly.test"        
[316] "napredict"            "qexp"                 "deriv"               
[319] "var"                  "aggregate.ts"         "rwilcox"             
[322] "SSbiexp"              "pt"                   "rsmirnov"            
[325] "qf"                   "xtabs"                "kruskal.test"        
[328] "median"               "as.hclust"            "termplot"            
[331] "rweibull"             "resid"                "pgeom"               
[334] "qnbinom"              "se.contrast"          "summary.manova"      
[337] "prcomp"               "preplot"              "plot.ecdf"           
[340] "arima.sim"            "lm.wfit"              "ccf"                 
[343] "is.leaf"              "na.action"            "screeplot"           
[346] "approxfun"            "NLSstAsymptotic"      "order.dendrogram"    
[349] "cycle"                "qt"                   "rf"                  
[352] "punif"                "quasi"                "ts.plot"             
[355] "cov.wt"               "mood.test"            "PP.test"             
[358] "is.empty.model"       "loess.control"        "decompose"           
[361] "aggregate"            "BIC"                  "reshape"             
[364] "makeARIMA"            "ARMAtoMA"             "weighted.mean"       
[367] "pbinom"               "selfStart"            "SSgompertz"          
[370] "qnorm"                "inverse.gaussian"     "na.omit"             
[373] "sd"                   "rt"                   "fft"                 
[376] "dcauchy"              "fivenum"              "toeplitz2"           
[379] "relevel"              "summary.glm"          "rexp"                
[382] "monthplot"            "dfbeta"               "diffinv"             
[385] "nobs"                 "SSmicmen"             "is.ts"               
[388] "dummy.coef.lm"        "hatvalues"            "variable.names"      
[391] "Pair"                 "model.frame.default"  "anova"               
[394] "simulate"             "dffits"               "model.matrix.default"
[397] "contr.SAS"            "contr.treatment"      "as.dendrogram"       
[400] "prop.trend.test"      "predict.lm"           "ppois"               
[403] "pcauchy"              "smoothEnds"           "qbinom"              
[406] "hat"                  "p.adjust"             ".MFclass"            
[409] "dbinom"               "terms.formula"        "spec.taper"          
[412] "HoltWinters"          "ts"                   "na.exclude"          
[415] "dsignrank"            "is.tskernel"          "fitted.values"       
[418] "qsignrank"            "integrate"            "optimise"            
[421] "binomial"             "KalmanSmooth"         ".vcov.aliased"       
[424] "deltat"               "SSD"                  "p.adjust.methods"    
[427] "smooth.spline"        "summary.lm"           "rstudent"            
[430] "dgeom"                "density"              "hclust"              
[433] "terms"                "fisher.test"          "rbinom"              
[436] "isoreg"               "nls.control"          "formula"             
[439] "contr.sum"            "uniroot"              "quasibinomial"       
[442] "dfbetas"              "na.contiguous"        "influence.measures"  
[445] "dunif"                "pairwise.prop.test"   "rnbinom"             
[448] "rbeta"                "pnorm"                "knots"               
[451] "cpgram"               "biplot"               "mad"                 
[454] "runmed"               "read.ftable"          "plogis"              
[457] "delete.response"      "aov"                  "update"              
[460] "StructTS"            

What users see: the search path

search()
 [1] ".GlobalEnv"        "package:rlang"     "package:stats"    
 [4] "package:graphics"  "package:grDevices" "package:utils"    
 [7] "package:datasets"  "package:methods"   "Autoloads"        
[10] "package:base"     

Namespaces via sd()

  • Note the environment!
sd
function (x, na.rm = FALSE) 
sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), 
    na.rm = na.rm))
<bytecode: 0x55cd1bc1abb0>
<environment: namespace:stats>
find("sqrt")
[1] "package:base"
find("var")
[1] "package:stats"
find("is.vector")
[1] "package:base"
find("is.factor")
[1] "package:base"
find("as.double")
[1] "package:base"

Namespace environments

ns_env("stats") |> env_parents()
[[1]] $ <env: imports:stats>
[[2]] $ <env: namespace:base>
[[3]] $ <env: global>
global_env() |> env_parents()
 [[1]] $ <env: package:rlang>
 [[2]] $ <env: package:stats>
 [[3]] $ <env: package:graphics>
 [[4]] $ <env: package:grDevices>
 [[5]] $ <env: package:utils>
 [[6]] $ <env: package:datasets>
 [[7]] $ <env: package:methods>
 [[8]] $ <env: Autoloads>
 [[9]] $ <env: package:base>
[[10]] $ <env: empty>

What developers see: the full picture

Huh?

Keep these in mind

  • Package environments (i.e., the search path) control what is available to users
  • Namespace environments control what is available to developers
  • (this will start to make more sense once we start developing packages!)

namespace:macleish

library(macleish)

macleish_created <- ns_env("macleish") |> 
  env_names()

macleish_created
 [1] ".__global__"                       "mass_gis"                         
 [3] "phenocam_image_url_midday"         ".packageName"                     
 [5] "phenocam_info"                     "phenocam_image_url"               
 [7] "phenocam_download"                 "phenocam_read_monthly_midday_urls"
 [9] "etl_extract.etl_macleish"          "phenocam_read_day_urls"           
[11] ".__NAMESPACE__."                   "macleish_intersect"               
[13] "etl_transform.etl_macleish"        ".__S3MethodsTable__."             
[15] "etl_transform_help"               

imports:macleish

  • objects from other packages that macleish developers use
macleish_imports <- ns_env("macleish") |> 
  env_parent() |>
  env_names()

length(macleish_imports)
[1] 322
macleish_imports
  [1] "slice_max"                  "expr"                      
  [3] "src"                        "db_desc"                   
  [5] "group_by_drop_default"      "db_commit"                 
  [7] "coalesce"                   "data_frame"                
  [9] "summarize_if"               "mutate_"                   
 [11] "db_create_index"            "join_by"                   
 [13] "check_dbplyr"               "src_tbls"                  
 [15] "db_query_rows"              "dense_rank"                
 [17] "slice_head"                 "tbl"                       
 [19] "last_col"                   "consecutive_id"            
 [21] "first"                      "arrange"                   
 [23] "dplyr_row_slice"            "read_csv"                  
 [25] "sql_semi_join"              "is.grouped_df"             
 [27] "summarise_each"             "group_vars"                
 [29] "bind_cols"                  "last_dplyr_warnings"       
 [31] "distinct_at"                "mutate_all"                
 [33] "relocate"                   "compute"                   
 [35] "mutate_if"                  "distinct_"                 
 [37] "group_indices_"             "eval_tbls2"                
 [39] "smart_upload"               "rename_all"                
 [41] "count"                      "src_mysql_cnf"             
 [43] "do_"                        "do"                        
 [45] "cumany"                     "recode_factor"             
 [47] "wrap_dbplyr_obj"            "same_src"                  
 [49] "top_frac"                   "select_vars"               
 [51] "desc"                       "db_create_indexes"         
 [53] "lead"                       "mutate_at"                 
 [55] "as_tibble"                  "distinct_prepare"          
 [57] "src_sqlite"                 "distinct_if"               
 [59] "add_row"                    ".data"                     
 [61] "etl_transform"              "cur_column"                
 [63] "semi_join"                  "filter_if"                 
 [65] "sql_translate_env"          "arrange_"                  
 [67] "case_match"                 "sql_set_op"                
 [69] "eval_tbls"                  "ensyms"                    
 [71] "arrange_at"                 "add_count"                 
 [73] "dplyr_reconstruct"          "slice_min"                 
 [75] "new_rowwise_df"             "cross_join"                
 [77] "setequal"                   "select"                    
 [79] "distinct_all"               "src_local"                 
 [81] "as.tbl"                     "summarise"                 
 [83] "type_sum"                   "db_drop_table"             
 [85] "rows_patch"                 "cur_data"                  
 [87] "row_number"                 "groups"                    
 [89] "anti_join"                  "tbl_vars"                  
 [91] "cur_group_id"               "st_intersection"           
 [93] "auto_copy"                  "sql_subquery"              
 [95] "group_indices"              "progress_estimated"        
 [97] "transmute_all"              "all_of"                    
 [99] "new_grouped_df"             "add_tally_"                
[101] "enquo"                      "group_data"                
[103] "contains"                   "rows_insert"               
[105] "all_equal"                  "group_split"               
[107] "tbl_ptype"                  "glimpse"                   
[109] "inner_join"                 "db_insert_into"            
[111] "db_save_query"              "etl_load"                  
[113] "etl"                        "id"                        
[115] "summarise_all"              "st_transform"              
[117] "ensym"                      "db_begin"                  
[119] "left_join"                  "everything"                
[121] "summarize_each_"            "valid_year_month"          
[123] "dplyr_col_modify"           "compare_tbls2"             
[125] "filter"                     "enquos"                    
[127] "union_all"                  "summarize_all"             
[129] "slice_tail"                 "where"                     
[131] "n"                          "quo"                       
[133] "add_count_"                 "summarize_each"            
[135] "show_query"                 "group_cols"                
[137] "summarise_at"               "n_distinct"                
[139] "transmute_at"               "extract_date_from_filename"
[141] "rename"                     "reframe"                   
[143] "select_vars_"               "etl_cleanup"               
[145] "near"                       "pick"                      
[147] "num_range"                  "sym"                       
[149] "n_groups"                   "across"                    
[151] "all_vars"                   "select_all"                
[153] "dbWipe"                     "slice"                     
[155] "na_if"                      "select_if"                 
[157] "grouped_df"                 "tbl_df"                    
[159] "tally_"                     "is.src"                    
[161] "etl_extract"                "intersect"                 
[163] "db_type"                    "db_create_table"           
[165] "%>%"                        "mutate_each"               
[167] "group_keys"                 "add_rownames"              
[169] "rename_vars"                "etl_init"                  
[171] "dbRunScript"                "select_at"                 
[173] "is.tbl"                     "arrange_all"               
[175] "summarize"                  "quo_name"                  
[177] "cummean"                    "rename_with"               
[179] "group_map"                  "current_vars"              
[181] "with_groups"                "syms"                      
[183] "last"                       "rowwise"                   
[185] "group_size"                 "union"                     
[187] "nth"                        "match_files_by_year_months"
[189] "src_postgres"               "enexprs"                   
[191] "dim_desc"                   "transmute"                 
[193] "any_of"                     "transmute_if"              
[195] "case_when"                  "arrange_if"                
[197] "order_by"                   "with_order"                
[199] "group_rows"                 "any_vars"                  
[201] "head"                       "db_analyze"                
[203] "db_data_type"               "as_data_frame"             
[205] "top_n"                      "add_tally"                 
[207] "enexpr"                     "db_query_fields"           
[209] "download.file"              "tribble"                   
[211] "group_trim"                 "between"                   
[213] "select_"                    "lag"                       
[215] "mutate_each_"               "find_schema"               
[217] "percent_rank"               "distinct"                  
[219] "as_label"                   "group_by_prepare"          
[221] "db_explain"                 "summarise_each_"           
[223] "tbl_nongroup_vars"          "bench_tbls"                
[225] "etl_create"                 "is_grouped_df"             
[227] "right_join"                 "summarise_if"              
[229] "filter_"                    "cur_group_rows"            
[231] "src_mysql"                  "summarize_at"              
[233] "lst"                        "etl_update"                
[235] "rows_delete"                "combine"                   
[237] "ntile"                      "location"                  
[239] "symdiff"                    "sql_escape_string"         
[241] "rename_vars_"               "nest_by"                   
[243] "db_rollback"                "quos"                      
[245] "filter_at"                  "collapse"                  
[247] "db_write_table"             "db_has_table"              
[249] "unzip"                      "starts_with"               
[251] "ungroup"                    "group_by"                  
[253] "funs"                       "vars"                      
[255] "if_all"                     "tibble"                    
[257] "slice_sample"               "recode"                    
[259] "validate_rowwise_df"        "rename_"                   
[261] "cur_group"                  "group_nest"                
[263] "filter_all"                 "one_of"                    
[265] "src_df"                     "summarise_"                
[267] "group_by_"                  "copy_to"                   
[269] "ends_with"                  "is.etl"                    
[271] "smart_download"             "cur_data_all"              
[273] "if_else"                    "setdiff"                   
[275] "transmute_"                 "funs_"                     
[277] "summarize_"                 "failwith"                  
[279] "ymd_hms"                    "compare_tbls"              
[281] "sample_frac"                "matches"                   
[283] "st_read"                    "group_by_all"              
[285] "create_etl_package"         "write_csv"                 
[287] "explain"                    "rename_if"                 
[289] "sample_n"                   "group_by_if"               
[291] "validate_grouped_df"        "common_by"                 
[293] "group_walk"                 "changes"                   
[295] "make_tbl"                   "rows_upsert"               
[297] "cume_dist"                  "ident"                     
[299] "rows_append"                "rows_update"               
[301] "select_var"                 "db_list_tables"            
[303] "rename_at"                  "sql_escape_ident"          
[305] "group_by_at"                "pull"                      
[307] "mutate"                     "nest_join"                 
[309] "slice_"                     "count_"                    
[311] "group_modify"               "if_any"                    
[313] "tally"                      "c_across"                  
[315] "bind_rows"                  "collect"                   
[317] "cumall"                     "min_rank"                  
[319] "sql_select"                 "sql"                       
[321] "full_join"                  "sql_join"                  

package:macleish

  • objects that macleish users can see

  • exported objects

macleish_exports <- pkg_env("macleish") |>
  env_names()

macleish_exports
 [1] "macleish_layers"                   "mass_gis"                         
 [3] ".Depends"                          "maple_sap"                        
 [5] "whately_2015"                      "phenocam_image_url_midday"        
 [7] "phenocam_image_url"                "phenocam_info"                    
 [9] "orchard_2015"                      "phenocam_read_monthly_midday_urls"
[11] "phenocam_read_day_urls"            "macleish_intersect"               
[13] "tree_diameter1"                    "tree_diameter2"                   
[15] "etl_transform_help"               

Now

Homework