---
title: "Considerations"
output:
html_document:
toc: true
toc_float:
collapsed: false
smooth_scroll: false
toc_depth: 2
vignette: >
%\VignetteIndexEntry{2. Considerations}
%\VignetteEncoding{UTF-8}
%\VignetteEngine{knitr::rmarkdown}
---
Thanks to **reticulate** is it possible to embed a Python session within an R session. The **[Earth Engine Python API](https://pypi.org/project/earthengine-api/)** and **rgee** share the **same modules, classes, functions, and methods**. In other words, the logic of the syntax is the same and just as fast (just change **.** by a **$**). Notwithstanding, differences in the language design of R and Python might cause some problems in specific scenarios. We identify **four** bug-potential cases. Each of them is explained in-depth below.
```{r, setup, include=FALSE}
knitr::opts_chunk$set(
comment = '', fig.width = 6, fig.height = 6
)
```
### **1. The map message error:**
This issue happens when the **map** method is used while: (1) running a reticulate version
lower than < 1.14 (please update it!); or (2) leading
with **ee$List** objects. For instance:
``` r
library(rgee)
ee$Initialize()
mylist = ee$List$sequence(10)
mylist$map(function(x) ee$Number(x)$add(1))
#> Error in py_call_impl(callable, dots$args, dots$keywords): RuntimeError: Evaluation error: argument "x" is missing, with no default.
#>
#> Detailed traceback:
#> File "/home/aybarpc01/.virtualenvs/r-reticulate/lib/python3.7/site-packages/ee/apifunction.py", line 205, in
#> return lambda *args, **kwargs: func.call(*args, **kwargs) # pylint: disable=unnecessary-lambda
#> File "/home/aybarpc01/.virtualenvs/r-reticulate/lib/python3.7/site-packages/ee/function.py", line 67, in call
#> return self.apply(self.nameArgs(args, kwargs))
#> File "/home/aybarpc01/.virtualenvs/r-reticulate/lib/python3.7/site-packages/ee/function.py", line 80, in apply
#> result = computedobject.ComputedObject(self, self.promoteArgs(named_args))
#> File "/home/aybarpc01/.virtualenvs/r-reticulate/lib/python3.7/site-packages/ee/function.py", line 107, in promoteArgs
#> promoted_args[name] = Function._promoter(args[name], spec['type'])
#> File "/home/aybarpc01/.virtualenvs/r-reticulate/lib/python3.7/site-packages/ee/__init__.py", line 242, in _Promote
#> return CustomFunction.create(arg, 'Object', ['Object'] * args_count)
#> File "/home/aybarpc01/.virtualenvs/r-reticulate/lib/python3.7/site-packages/ee/customfunction.py", line 121, in create
#> return CustomFunction(signature, func)
#> File "/home/aybarpc01/.virtualenvs/r-reticulate/lib/python3.7/site-packages/ee/customfunction.py", line 47, in __init__
#> self._body = body(*variables)
#> File "/home/aybarpc01/R/x86_64-pc-linux-gnu-library/3.6/reticulate/python/rpytools/call.py", line 21, in python_function
#> raise RuntimeError(res[kErrorKey])
```
The code before is perfectly valid but `rgee` will produce an error.
This problem should be easily solved by adding the function **ee_utils_pyfunc**.
It will permit to wrap R functions before to send it to `reticulate`. Let’s see:
``` r
library(rgee)
ee$Initialize()
mylist = ee$List$sequence(0,10)
mynewlist = mylist$map(
ee_utils_pyfunc(
function(x) ee$Number(x)$add(1)
)
)
mynewlist$getInfo()
#> [1] 1 2 3 4 5 6 7 8 9 10 11
```
### **2. Do not forget the L**
By default, when you define a number in R it will produce a **double
precision** value. This does not happen in Python because, by default it
will create an **int** value.
**Python**
``` python
type(1)
#>
```
**R**
``` r
class(1)
#> [1] "numeric"
```
But why does this matter? Let's explain with an example:
**Python**
``` python
ee.Initialize()
and_bitwise = ee.Number(32).bitwiseAnd(100)
and_bitwise.getInfo()
#> 32
```
**R**
``` r
and_bitwise = ee$Number(32)$bitwiseAnd(100) #caution: silent error
and_bitwise$getInfo()
Traceback (most recent call last):
File "", line 1, in
File "/home/aybarpc01/.local/lib/python3.7/site-packages/ee/computedobject.py", line 95, in getInfo
return data.computeValue(self)
File "/home/aybarpc01/.local/lib/python3.7/site-packages/ee/data.py", line 490, in computeValue
return send_('/value', ({'json': obj.serialize(), 'json_format': 'v2'}))
File "/home/aybarpc01/.local/lib/python3.7/site-packages/ee/data.py", line 1186, in send_
raise ee_exception.EEException(json_content['error']['message'])
ee.ee_exception.EEException: Number.bitwiseAnd: Bitwise operands must be integer only.
```
Users need to take into consideration that most of the arguments of the
Earth Engine methods are strict to admit only **integer values**. The
creation of integers in R is quite simple; you just need to add the
letter **L** to the end of the specific number or employ the
function `as.integer`. The **correct code** in R would be:
``` r
and_bitwise = ee$Number(32L)$bitwiseAnd(100L)
and_bitwise$getInfo()
#> [1] 32
```
### **3. Be careful with ee$Date**
This problem also appears due to differences between the design of R and
Python as programming languages. Currently, R only supports integer data
type of 32 bits. Such integers can only count up to about 2 billion. Unfortunately,
this range is insufficient to deal with [Google Earth
Engine timestamp](https://developers.google.com/earth-engine/glossary/)
which is saved in milliseconds since the [UNIX epoch](https://en.wikipedia.org/wiki/Unix_time).
**Python**
``` python
my_date = ee.Date('1990-01-01')
my_date.getInfo()
#> {'type': 'Date', 'value': 631152000000} # greater than 2 billion
```
**R**
``` r
my_date <- ee$Date('1990-01-01')
my_date$getInfo()
#> $type
#> [1] "Date"
#>
#> $value
#> [1] -208192512
```
The problems with `ee$Date` just appear in the last mile (Python to R or
vice-versa, `reticulate`), and they should not be too severe if treated
with care. `rgee` implements two functions to deal with Earth Engine
dates: `eedate_to_rdate` and `rdate_to_eedate`.
``` r
# Era5 dataset
era_img <- ee$ImageCollection("ECMWF/ERA5/DAILY")$
filterDate("2019-01-01", "2019-12-31")$
first()
# Extracting init date
ee_date <- era_img$get('system:time_start')
ee_date$getInfo() # Silent error
#> [1] 112573440
eedate_to_rdate(ee_date = ee_date, timestamp = TRUE)
#> [1] 1.546301e+12
```
### **4. Take into consideration reserved words in R**
A reserved word is a word that cannot be used as an identifier, such as the name
of a variable or a function. According with `?reserved`, the reserved words in R's parser
are: `if`, `else`, **`repeat`**, `while`, `function`, `for`, `in`, `next`, `break`, `TRUE`, `FALSE`, `NULL`,
`Inf`, `NaN`, `NA`, `NA_integer_`, `NA_real_`, `NA_complex_`, `NA_character_`. Of these words,
the only one that is part of the Earth Engine API is **repeat**.
We can find **repeat** as a
method for an Earth Engine List object. See **[`ee$List$repeat(value, count)`](https://developers.google.com/earth-engine/apidocs/ee-list-repeat)**:
``` r
library(rgee)
ee_Initialize()
ee_list <- ee$List(1:10)
ee_list$repeat(10,2)$getInfo()
#> Error: unexpected 'repeat' in "ee_list$repeat"
```
To avoid this error use backticks/quotation marks:
``` r
library(rgee)
ee_Initialize()
ee_list <- ee$List(1:10)
ee_list$'repeat'(10,2)$getInfo()
#> 10 10
```