«ValueError: коды должны быть между -1 и len (категории) -1» при извлечении нулевых значений в rpy2 - PullRequest
0 голосов
/ 10 ноября 2018

При использовании rpy2 со встроенным набором данных из пакета synthpop R (SD2011) я получаю эту ошибку:

robjects.r('head(SD2011)')
# ...
# ValueError: codes need to be between -1 and len(categories)-1

Я свернул проблему в столбец, которыйимеет пустые записи, например, я получаю ту же ошибку при этом, но не смежные строки или столбцы:

robjects.r('SD2011[3, 27]')

Я подтвердил, что это нулевое значение с:

robjects.r('is.na(SD2011[, 27])')
# array([0, 0, 1, ..., 0, 0, 0], dtype=int32)

Почемуrpy2 не справляется с этим изящно?

Вот мой ноутбук пробегает его.

1 Ответ

0 голосов
/ 10 ноября 2018

Почему rpy2 не обрабатывает это изящно?

Это похоже на ошибку, вызванную преобразованием R-фактора в панд с rpy2 версии 2.9.x (ветка dev default, в будущем 3.0.x, не имеет этой проблемы). В частности, при выполнении:

res = pandas.Categorical.from_codes(numpy.asarray(obj) - 1,
                                    categories = obj.do_slot('levels'),
                                    ordered = 'ordered' in obj.rclass)

R «факторные» объекты - это вектор целых чисел, причем каждое целое число является индексом в соответствующем векторе «уровней». Преобразователь просто вычитает единицу, потому что массивы R индексируются одним индексом, а массивы Python имеют нулевой индекс, но это нарушается всякий раз, когда отсутствуют пропущенные значения (NA), поскольку R использует конкретное целое число для кодирования пропущенных целых чисел (экстремальное значение) и Python, numpy и pandas не имеют эквивалента для этого.

Я открыл проблему , чтобы отследить этот , и тем временем можно обойти эти проблемы, чтобы заменить NA на стороне R на уровень (и назвать их, скажем, «пропавшими» или «NA») измените коэффициенты на массивы строк или измените преобразователь панд для коэффициентов R. Например:

robjects.r("""
  SD2011_nofactor <- SD2011 %>%
    dplyr::mutate_if(is.factor,
                     funs(as.character(.))
""")

(Или используйте Python-интерфейс rpy2 для dplyr )

Примечание:

Мало что происходит при выполнении:

robjects.r('SD2011[3, 27]')
  1. оценивается код R SD2011[3, 27]
  2. результат этой оценки проходит преобразование на уровне роботов
  3. объект, полученный в результате этого преобразования, отображается в вашей записной книжке

Если вы не уверены, обнаружение того, какое из приведенных ниже утверждений Python является первым неудачным, может сказать об этом:

  1. Оценить код R (добавлено TRUE для предотвращения возврата оценки x).

    robjects.r('x <- SD2011[3, 27]; TRUE')
    
  2. Получите объект x, полученный из приведенной выше оценки, и привяжите его к символу Python (преобразование будет применено).

    x = robjects.r('x')
    
  3. Показать текстовое представление преобразованного объекта

    repr(x)
    
...