0
# Environment Management
1
2
Work with R environments, scoping, and evaluation contexts for advanced R programming patterns from Python, including variable management, namespace isolation, and function scoping.
3
4
## Capabilities
5
6
### Environment Interface
7
8
R environments provide variable scoping and namespace management with dict-like Python interface.
9
10
```python { .api }
11
class Environment(RObject):
12
"""
13
R environment wrapper with dict-like interface.
14
15
Provides Python-style access to R environments for
16
variable storage, scoping, and namespace management.
17
"""
18
def __getitem__(self, key: str):
19
"""
20
Get variable from environment.
21
22
Parameters:
23
- key: Variable name
24
25
Returns:
26
R object value
27
28
Raises:
29
KeyError: If variable not found
30
"""
31
32
def __setitem__(self, key: str, value):
33
"""
34
Set variable in environment.
35
36
Parameters:
37
- key: Variable name
38
- value: Value to assign (converted to R object)
39
"""
40
41
def __delitem__(self, key: str):
42
"""
43
Remove variable from environment.
44
45
Parameters:
46
- key: Variable name to remove
47
48
Raises:
49
KeyError: If variable not found
50
"""
51
52
def __contains__(self, key: str) -> bool:
53
"""
54
Check if variable exists in environment.
55
56
Parameters:
57
- key: Variable name
58
59
Returns:
60
True if variable exists
61
"""
62
63
def keys(self):
64
"""
65
Get all variable names in environment.
66
67
Returns:
68
Iterator over variable names
69
"""
70
71
def values(self):
72
"""
73
Get all values in environment.
74
75
Returns:
76
Iterator over variable values
77
"""
78
79
def items(self):
80
"""
81
Get all name-value pairs in environment.
82
83
Returns:
84
Iterator over (name, value) tuples
85
"""
86
87
def get(self, key: str, default=None):
88
"""
89
Get variable with default value.
90
91
Parameters:
92
- key: Variable name
93
- default: Default value if not found
94
95
Returns:
96
Variable value or default
97
"""
98
```
99
100
### Standard Environments
101
102
Predefined R environments for different scoping contexts.
103
104
```python { .api }
105
# Global environments
106
globalenv: Environment # R global environment (.GlobalEnv)
107
baseenv: Environment # R base environment
108
emptyenv: Environment # R empty environment
109
110
# Access to current environments
111
def get_globalenv() -> Environment:
112
"""Get R global environment."""
113
114
def get_baseenv() -> Environment:
115
"""Get R base environment."""
116
117
def get_emptyenv() -> Environment:
118
"""Get R empty environment."""
119
```
120
121
### Environment Creation
122
123
Create new R environments with specified parent environments.
124
125
```python { .api }
126
def new_env(parent=None, hash: bool = True, size: int = 29) -> Environment:
127
"""
128
Create new R environment.
129
130
Parameters:
131
- parent: Parent environment (default: global environment)
132
- hash: Use hash table for variable lookup (default: True)
133
- size: Initial hash table size (default: 29)
134
135
Returns:
136
New environment instance
137
"""
138
```
139
140
### Context Management
141
142
Manage evaluation contexts and temporary environments.
143
144
```python { .api }
145
def local_context(env: Environment = None, use_rlock: bool = True):
146
"""
147
Context manager for local R evaluation environment.
148
149
Parameters:
150
- env: Environment to use (default: new environment)
151
- use_rlock: Use R's thread lock for safety (default: True)
152
153
Returns:
154
Context manager that sets evaluation environment
155
156
Usage:
157
with local_context() as env:
158
# Code here evaluates in local environment
159
env['x'] = 42
160
result = r('x + 10') # Uses local x
161
# x no longer accessible outside context
162
"""
163
164
class evaluation_context:
165
"""
166
Context variable managing current R evaluation environment.
167
168
Used internally by rpy2 to track the active environment
169
for R code evaluation and variable resolution.
170
"""
171
def get(self) -> Environment: ...
172
def set(self, env: Environment): ...
173
```
174
175
### Environment Hierarchy
176
177
Navigate and manipulate R environment inheritance chains.
178
179
```python { .api }
180
class Environment:
181
@property
182
def parent(self) -> Environment:
183
"""Get parent environment in inheritance chain."""
184
185
@parent.setter
186
def parent(self, env: Environment):
187
"""Set parent environment."""
188
189
def parents(self):
190
"""
191
Iterate through parent environments.
192
193
Yields:
194
Environment objects from current to base environment
195
"""
196
197
def find(self, name: str) -> Environment:
198
"""
199
Find environment containing variable.
200
201
Parameters:
202
- name: Variable name to search for
203
204
Returns:
205
Environment containing the variable
206
207
Raises:
208
KeyError: If variable not found in hierarchy
209
"""
210
```
211
212
### Environment Utilities
213
214
Helper functions for environment inspection and manipulation.
215
216
```python { .api }
217
def env_to_list(env: Environment) -> dict:
218
"""
219
Convert environment to Python dictionary.
220
221
Parameters:
222
- env: Environment to convert
223
224
Returns:
225
Dictionary with environment contents
226
"""
227
228
def list_to_env(data: dict, parent: Environment = None) -> Environment:
229
"""
230
Create environment from Python dictionary.
231
232
Parameters:
233
- data: Dictionary with variable names and values
234
- parent: Parent environment (default: global environment)
235
236
Returns:
237
New environment with dictionary contents
238
"""
239
240
def env_size(env: Environment) -> int:
241
"""
242
Get number of variables in environment.
243
244
Parameters:
245
- env: Environment to measure
246
247
Returns:
248
Number of variables
249
"""
250
251
def env_ls(env: Environment, all_names: bool = False) -> list:
252
"""
253
List variable names in environment.
254
255
Parameters:
256
- env: Environment to list
257
- all_names: Include hidden variables (starting with .)
258
259
Returns:
260
List of variable names
261
"""
262
```
263
264
### Usage Examples
265
266
```python
267
import rpy2.robjects as ro
268
from rpy2.robjects import r, globalenv
269
from rpy2.robjects.environments import Environment
270
271
# Access global environment
272
print(f"Variables in global env: {list(globalenv.keys())}")
273
274
# Set variables in global environment
275
globalenv['my_var'] = ro.IntVector([1, 2, 3, 4, 5])
276
globalenv['my_string'] = 'Hello from Python'
277
278
# Access variables from R
279
result = r('mean(my_var)')
280
print(f"Mean: {result[0]}")
281
282
# Check if variables exist
283
if 'my_var' in globalenv:
284
print("my_var exists in global environment")
285
286
# Get variable with default
287
value = globalenv.get('nonexistent_var', 'default_value')
288
print(f"Value: {value}")
289
290
# Create new environment
291
my_env = ro.robjects.environments.new_env()
292
my_env['local_var'] = ro.FloatVector([1.1, 2.2, 3.3])
293
294
# Environment hierarchy
295
print(f"Parent of my_env: {my_env.parent}")
296
297
# Find environment containing variable
298
env_with_var = globalenv.find('my_var')
299
print(f"Found my_var in: {env_with_var}")
300
301
# Use local context for temporary variables
302
with ro.robjects.environments.local_context() as local_env:
303
local_env['temp_var'] = 42
304
local_env['temp_list'] = ro.IntVector([10, 20, 30])
305
306
# These variables are only available in this context
307
result = r('temp_var + sum(temp_list)')
308
print(f"Local result: {result[0]}")
309
310
# temp_var and temp_list are no longer accessible
311
try:
312
print(globalenv['temp_var'])
313
except KeyError:
314
print("temp_var not found in global environment (as expected)")
315
316
# Environment as dictionary
317
env_dict = {
318
'x': ro.IntVector([1, 2, 3]),
319
'y': ro.FloatVector([1.1, 2.2, 3.3]),
320
'name': 'test_environment'
321
}
322
323
dict_env = ro.robjects.environments.list_to_env(env_dict)
324
print(f"Variables in dict_env: {list(dict_env.keys())}")
325
326
# Convert environment back to dictionary
327
back_to_dict = ro.robjects.environments.env_to_list(dict_env)
328
print(f"Back to dict: {back_to_dict.keys()}")
329
330
# Environment iteration
331
print("All variables and values in global environment:")
332
for name, value in globalenv.items():
333
print(f" {name}: {type(value)}")
334
335
# Environment cleanup
336
del globalenv['my_var']
337
del globalenv['my_string']
338
339
# Working with package environments
340
stats_env = ro.packages.importr('stats').__renv__
341
print(f"Functions in stats package: {len(list(stats_env.keys()))}")
342
343
# Search path environments (R search() equivalent)
344
search_envs = []
345
current = globalenv
346
while current is not None:
347
search_envs.append(current)
348
try:
349
current = current.parent
350
except:
351
break
352
353
print(f"Number of environments in search path: {len(search_envs)}")
354
```
355
356
### Advanced Environment Patterns
357
358
```python
359
# Environment-based namespacing
360
class RNamespace:
361
"""Python class wrapping R environment for namespace management."""
362
363
def __init__(self, name):
364
self.name = name
365
self.env = ro.robjects.environments.new_env()
366
globalenv[name] = self.env
367
368
def __setattr__(self, name, value):
369
if name in ['name', 'env']:
370
super().__setattr__(name, value)
371
else:
372
self.env[name] = value
373
374
def __getattr__(self, name):
375
return self.env[name]
376
377
# Create namespace
378
my_namespace = RNamespace('my_package')
379
my_namespace.utility_function = r('function(x) x^2')
380
my_namespace.constant = 3.14159
381
382
# Use from R
383
result = r('my_package$utility_function(5)')
384
print(f"Result: {result[0]}") # 25.0
385
386
# Function factories with closures
387
def create_r_function_factory(base_env):
388
"""Create R functions with specific environment closures."""
389
390
factory_env = ro.robjects.environments.new_env(parent=base_env)
391
factory_env['multiplier'] = 10
392
393
with ro.robjects.environments.local_context(factory_env):
394
r_function = r('''
395
function(x) {
396
x * multiplier
397
}
398
''')
399
400
return r_function
401
402
# Create function with closure
403
multiplier_func = create_r_function_factory(globalenv)
404
result = multiplier_func(ro.IntVector([1, 2, 3, 4, 5]))
405
print(f"Multiplied: {list(result)}") # [10, 20, 30, 40, 50]
406
```