Question: I am trying to utilize some R based packages within a Python script using the rpy2 package. In order to implement the code, I first need to convert a Pandas dataframe into an R based data matrix. However, something incredibly strange is happening to the values within the code. Here is a minimally reproducible example of the code import pandas as pd import numpy as np import rpy2.robjects as ro from rpy2.robjects.packages import importr from rpy2.robjects import pandas2ri pandas2ri.activate() utils = importr('utils') # Function to generate random column names def generate_column_names(n, suffixes): columns = [] for _ in range(n): name = ''.join(random.choices(string.ascii_uppercase, k=3)) # Random 3-character string suffix = random.choice(suffixes) # Randomly choose between "_Healthy" and "_Sick" columns.append(name + suffix) return columns # Number of rows and columns n_rows = 1000 n_cols = 15 # Generate random float values between 0 and 10 data = np.random.uniform(0, 10, size=(n_rows, n_cols)) # Introduce NaN values sporadically nan_indices = np.random.choice([True, False], size=data.shape, p=[0.1, 0.9]) data[nan_indices] = np.nan # Generate random column names column_names = generate_column_names(n_cols, ["_Healthy", "_Sick"]) # Create the DataFrame df = pd.DataFrame(data, columns=column_names) df = df.replace(np.nan, "NA") with localconverter(ro.default_converter + pandas2ri.converter): R_df = ro.conversion.py2rpy(df) r_matrix = r('data.matrix')(R_df)  Now, the input Pandas dataframe looks like this:  However, after turning it into a R based dataframe using ro.conversion.py2rpy(), and then recasting that as a data matrix using r('data.matrix'), I get a r_matrix dataframe that look like this:  How could this happen? I have checked the intermediate R_df and have found that it has the same values as the input Pandas df, so it seems that the line r('data.matrix') is drastically altering my contents. I have run the analogous commands in R (after importing the exact same dataframe into R using readr), and data.matrix does not affect my dataframe's contents at all, so I am incredibly confused as to what the problem is. Has anyone else experienced this at all?

Answer: Your column is being coerced to a factor and then numeric When in Python you do df = df.replace(np.nan, "NA"), you are replacing with the literal string "NA". That means that the "NA" values are then stored as an object rather than float64. Unlike pandas, R does not have an object type. Columns (or vectors in R) need to all be the same type. If a vector contains numeric and string values, R ultimately treats the whole thing as character. The behaviour that you get with a character vector using data.matrix() is:  Character columns are first converted to factors and then to integers.  For example: set.seed(1) (df <- data.frame( x = 1:5, y = (as.character(rnorm(5))) )) # x y # 1 1 -0.626453810742332 # 2 2 0.183643324222082 # 3 3 -0.835628612410047 # 4 4 1.59528080213779 # 5 5 0.32950777181536 data.matrix(df) # x y # [1,] 1 1 # [2,] 2 3 # [3,] 3 2 # [4,] 4 5 # [5,] 5 4  Use NA_real_ There is a class rpy2.rinterface_lib.sexp.NARealType. You need to instantiate this and then replace np.nan with this object. This means the entire column can remain a float64 in Python, and numeric in R, so there is no coercion to factor. na = rpy2.rinterface_lib.sexp.NARealType() df2 = df.replace(np.nan, na) with localconverter(ro.default_converter + pandas2ri.converter): R_df = ro.conversion.py2rpy(df2) r_matrix = ro.r('data.matrix')(R_df) r_matrix  Output: array([[6.71551482, 3.37235768, 1.73878498, ..., 9.26968137, 4.44605036, 0.57638575], [2.14651571, 5.14706755, 7.43517449, ..., 7.56905516, 3.1960465 , 9.13240441], [0.67569123, 8.55601696, 3.34151056, ..., nan, 4.12252086, 5.79825217], ..., [2.93515376, 2.29766304, 2.70761156, ..., 7.80345898, 0.34809462, 4.5128469 ], [5.66194126, 1.32135235, 2.57649142, ..., 3.49908635, 3.77794316, 8.96322655], [8.43950172, 1.65306388, 7.37031975, ..., 8.01045219, 8.68857319, 7.51309124]])