Raniere Silva
Raniere Silva

Reputation: 2697

How to call Python method from R reticulate

reticulate lets you interface with Python from R. In Python, it is common to use (class) methods to interact with your variables. How do I access/execute the method of one Python variable in R when using reticulate? For example, if I create the following Python dictionary:

```{python}
fruits = {
    "apple": 53,
    "banana": None,
    "melon": 7,
}
```

that is accessible using reticulate,

```{r}
py$fruits
```

## $apple
## [1] 53
## 
## $banana
## NULL
## 
## $melon
## [1] 7

How can I call one of the methods from the dictionary class, e.g. keys() from R?

```{python}
print(fruits.keys())
```

## dict_keys(['apple', 'banana', 'melon'])

I tried:

```{r error=TRUE}
py$fruits$keys()
```

## Error in eval(expr, envir, enclos): attempt to apply non-function

```{r error=TRUE}
py$fruits.keys()
```

## Error in py_get_attr_impl(x, name, silent): AttributeError: module '__main__' has no attribute 'fruits.keys'

but both tries failed.

Upvotes: 5

Views: 1727

Answers (2)

f0nzie
f0nzie

Reputation: 1206

Applying a little bit of introspection on the original Python chunk:

```{python}
fruits = {
"apple": 53,
"banana": None,
"melon": 7,
}
```

In another R chunk:

```{r}
py_fruits <- r_to_py(py$fruits)
py_list_attributes(py_fruits)
py_fruits$keys()
py_fruits$items()
```

You will get (1) all the attributes available for the Python object, (2) the dict keys; (3) dict item; and (4) the dict values:

enter image description here

Observe the conversion from an R to Python object with r_to_py().

If you want to dig deeper, you can also do this:

```{r}
library(reticulate)
builtins    <- import_builtins()

builtins$dict$keys(py$fruits)     # keys
builtins$dict$items(py$fruits)    # items
builtins$dict$values(py$fruits)   # values

enter image description here

Upvotes: 0

Artem Sokolov
Artem Sokolov

Reputation: 13691

As pointed out in Type Conversions, Python's dict objects become named lists in R. So, to access the equivalent of "dictionary keys" in R you would use names:

```{r}
names(py$fruits)
```
## [1] "melon"  "apple"  "banana"

You may choose to convert the result back to a dict-like object using reticulate::dict(). The resulting object would then function as you want:

```{r}
reticulate::dict( py$fruits )
```
## {'melon': 7, 'apple': 53, 'banana': None}

```{r}
reticulate::dict( py$fruits )$keys()
```
## ['melon', 'apple', 'banana']

Upvotes: 5

Related Questions