I have some problems using the rpy2 package

35 views Asked by At

In this code, I cannot convert the variable cpgraph into the <class 'rpy2.robjects.vectors.IntMatrix'> type using ordinary robjects.r.matrix statements. Is it because my graph is more complicated?

here is the code

def sample_graphs(mpgraph, n_graphs=10, equal_weights=False):
    graphs = []
    if nx.is_directed_acyclic_graph(nx.DiGraph(mpgraph)):
        graphs.append((mpgraph.copy(), n_graphs))
    else:
        n_vars = mpgraph.shape[0]

        addBgKnowledge = robjects.r['addBgKnowledge']
        for _ in range(n_graphs):
            graph = mpgraph.copy()
            undirected_u, undirected_v = np.nonzero(np.triu(graph == graph.T) & (graph == 1))

            while len(undirected_u) > 0:
                selected_edge_idx = np.random.randint(0, len(undirected_u))
                u, v = undirected_u[selected_edge_idx], undirected_v[selected_edge_idx]
                if np.random.rand() < 0.5:
                    u, v = v, u

                numpy2ri.activate()
                pandas2ri.activate()

                cpgraph = robjects.r.matrix(graph, nrow=n_vars, ncol=n_vars)
                print(cpgraph)
                print(type(cpgraph))
                cpgraph.rownames = robjects.StrVector([str(i) for i in range(n_vars)])
                cpgraph.colnames = robjects.StrVector([str(i) for i in range(n_vars)])
                cpgraph = r_as(cpgraph, 'graphNEL')

                numpy2ri.deactivate()
                pandas2ri.deactivate()

                graph = r_as(addBgKnowledge(cpgraph, x=[str(u)], y=[str(v)]), 'matrix').astype(int)

                undirected_u, undirected_v = np.nonzero(np.triu(graph == graph.T) & (graph == 1))


            found = False

            for idx, (comp_graph, weight) in enumerate(graphs):
                if (comp_graph == graph).all():
                    graphs[idx] = (graph, weight + 1)
                    found = True
                    break

            if not found:
                graphs.append((graph, 1))

    if equal_weights:
        graphs = [(graph, 1 / len(graphs)) for graph, _ in graphs]
    else:
        graphs = [(graph, w / n_graphs) for graph, w in graphs]
    return graphs

I tried writing a separate piece of code to check the availability of the rpy2 package to prove that it is available.

import rpy2.robjects as robjects
from rpy2.robjects import numpy2ri
import numpy as np
import networkx as nx

numpy2ri.activate()
data = np.array(\[1, 2, 3, 4\])
r_matrix = robjects.r.matrix(data, nrow=2, ncol=2)
print(type(r_matrix))

print(nx.__version__)

The output is: <class 'rpy2.robjects.vectors.IntMatrix'> 2.5

1

There are 1 answers

0
lgautier On

Using the .activate() methods is discouraged. Prefer a local converter (see doc here).

Beside that, what you must ensure is that your Python object graph can either be converted into an R sequence passed to the R function matrix() (see doc here), or can directly be converted into an R matrix using rpy2's conversion rule sets (numpy matrix to R matrix is what numpy2ri.converter alone can do). graph appears to be a copy of mpgraph so that's the python type you'll have to look at.