@@ -181,7 +181,18 @@ def convert_robj(obj, use_pandas=True):
181
181
np .int32 : robj .IntVector ,
182
182
np .int64 : robj .IntVector ,
183
183
np .object_ : robj .StrVector ,
184
- np .str : robj .StrVector }
184
+ np .str : robj .StrVector ,
185
+ np .bool : robj .BoolVector }
186
+
187
+ NA_TYPES = {np .float64 : robj .NA_Real ,
188
+ np .float32 : robj .NA_Real ,
189
+ np .float : robj .NA_Real ,
190
+ np .int : robj .NA_Integer ,
191
+ np .int32 : robj .NA_Integer ,
192
+ np .int64 : robj .NA_Integer ,
193
+ np .object_ : robj .NA_Character ,
194
+ np .str : robj .NA_Character ,
195
+ np .bool : robj .NA_Logical }
185
196
186
197
def convert_to_r_dataframe (df , strings_as_factors = False ):
187
198
"""
@@ -207,8 +218,9 @@ def convert_to_r_dataframe(df, strings_as_factors=False):
207
218
for column in df :
208
219
value = df [column ]
209
220
value_type = value .dtype .type
210
- value = [item if pn .notnull (item ) else robj . NA_Real
221
+ value = [item if pn .notnull (item ) else NA_TYPES [ value_type ]
211
222
for item in value ]
223
+
212
224
value = VECTOR_TYPES [value_type ](value )
213
225
214
226
if not strings_as_factors :
@@ -242,6 +254,11 @@ def convert_to_r_matrix(df, strings_as_factors=False):
242
254
243
255
"""
244
256
257
+ if df ._is_mixed_type :
258
+ raise TypeError ("Conversion to matrix only possible with non-mixed "
259
+ "type DataFrames" )
260
+
261
+
245
262
r_dataframe = convert_to_r_dataframe (df , strings_as_factors )
246
263
as_matrix = robj .baseenv .get ("as.matrix" )
247
264
r_matrix = as_matrix (r_dataframe )
@@ -291,34 +308,67 @@ def test_convert_matrix():
291
308
292
309
def test_convert_r_dataframe ():
293
310
311
+ is_na = robj .baseenv .get ("is.na" )
312
+
294
313
seriesd = _test .getSeriesData ()
295
314
frame = pn .DataFrame (seriesd , columns = ['D' , 'C' , 'B' , 'A' ])
296
315
316
+ #Null data
317
+ frame ["E" ] = [np .nan for item in frame ["A" ]]
318
+ # Some mixed type data
319
+ frame ["F" ] = ["text" if item % 2 == 0 else np .nan for item in range (30 )]
320
+
297
321
r_dataframe = convert_to_r_dataframe (frame )
298
322
299
323
assert np .array_equal (convert_robj (r_dataframe .rownames ), frame .index )
300
324
assert np .array_equal (convert_robj (r_dataframe .colnames ), frame .columns )
325
+ assert all (is_na (item ) for item in r_dataframe .rx2 ("E" ))
301
326
302
- for column in r_dataframe . colnames :
327
+ for column in frame [[ "A" , "B" , "C" , "D" ]] :
303
328
coldata = r_dataframe .rx2 (column )
304
329
original_data = frame [column ]
305
330
assert np .array_equal (convert_robj (coldata ), original_data )
306
331
332
+ for column in frame [["D" , "E" ]]:
333
+ for original , converted in zip (frame [column ],
334
+ r_dataframe .rx2 (column )):
335
+
336
+ if pn .isnull (original ):
337
+ assert is_na (converted )
338
+ else :
339
+ assert original == converted
340
+
307
341
def test_convert_r_matrix ():
308
342
343
+ is_na = robj .baseenv .get ("is.na" )
344
+
309
345
seriesd = _test .getSeriesData ()
310
346
frame = pn .DataFrame (seriesd , columns = ['D' , 'C' , 'B' , 'A' ])
347
+ #Null data
348
+ frame ["E" ] = [np .nan for item in frame ["A" ]]
311
349
312
350
r_dataframe = convert_to_r_matrix (frame )
313
351
314
352
assert np .array_equal (convert_robj (r_dataframe .rownames ), frame .index )
315
353
assert np .array_equal (convert_robj (r_dataframe .colnames ), frame .columns )
354
+ assert all (is_na (item ) for item in r_dataframe .rx (True , "E" ))
316
355
317
- for column in r_dataframe . colnames :
356
+ for column in frame [[ "A" , "B" , "C" , "D" ]] :
318
357
coldata = r_dataframe .rx (True , column )
319
358
original_data = frame [column ]
320
- assert np .array_equal (convert_robj (coldata ), original_data )
359
+ assert np .array_equal (convert_robj (coldata ),
360
+ original_data )
361
+
362
+ # Pandas bug 1282
363
+ frame ["F" ] = ["text" if item % 2 == 0 else np .nan for item in range (30 )]
321
364
365
+ #FIXME: Ugly, this whole module needs to be ported to nose/unittest
366
+ try :
367
+ wrong_matrix = convert_to_r_matrix (frame )
368
+ except TypeError :
369
+ pass
370
+ except Exception :
371
+ raise
322
372
323
373
324
374
if __name__ == '__main__' :
0 commit comments