Получите чистую сводку nlme.lme() или lme4.lmer() в RPy

Я взаимодействую с функциями nlme и lme4 R через RPy, и я хотел бы получить доступ к сводке вывода из моей консоли Python.

Я запускаю следующий код:

test1=nlme.lme(r.formula('Pupil~CoI*Time'), random=r.formula('~1|ID'),data=dfr)
test2=nlme.lme(r.formula('Pupil~CoI*measurement'),random=r.formula('~1|ID'),data=dfr)
test1_sum= r.summary(test1)
test2_sum= r.summary(test2)
print test1_sum
print test2_sum

для nlme, а это для lme4:

test1=lme4.lmer(r.formula('Pupil~CoI*Time+(1|ID)'),data=dfr)
test2=lme4.lmer(r.formula('Pupil~CoI*measurement+(1|ID)'),data=dfr)
test1_sum= r.summary(test1)
test2_sum= r.summary(test2)
print test1_sum
print test2_sum

Чтобы получить фрагмент кода с данными и явным импортом, обратитесь к этому блокнот IPython.

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

Data: structure(list(CoI = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L ......

Я хотел бы получить более подробное резюме по строкам:

Random effects:
 Formula: ~1 | ID
        (Intercept)  Residual
StdDev:   0.2201214 0.1199874

Fixed effects: Pupil ~ CoI * measurement 
                         Value  Std.Error   DF   t-value p-value
(Intercept)          1.2068660 0.06369911 5769 18.946357       0
CoIhard             -0.0394413 0.00629117 5769 -6.269306       0
measurement         -0.0002743 0.00003207 5769 -8.554287       0
CoIhard:measurement  0.0005227 0.00004536 5769 11.524511       0
 Correlation: 
                    (Intr) CoIhrd msrmnt
CoIhard             -0.049              
measurement         -0.060  0.612       
CoIhard:measurement  0.043 -0.865 -0.707

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max 
-9.86773055 -0.37638950  0.02085029  0.43203795  4.97364143 

Number of Observations: 5784
Number of Groups: 12 

(что входит в то, что я получаю, но после всего вышеперечисленного идут только тысячи записей) Как мне этого добиться?


person TheChymera    schedule 14.06.2014    source источник
comment
Дайте мне знать, поможет ли этот пост: на rpy2">stackoverflow.com/questions/22693059/, или вам нужен индивидуальный ответ.   -  person CT Zhu    schedule 14.06.2014
comment
В некотором роде. Это, однако, другая функция и немного другой вопрос. но теперь я понимаю, что я могу нарезать сводку с такими индексами, как summary[2]. Есть ли способ использовать имена из summary.names напрямую? как summary["tTable"]? В настоящее время я получаю 'str' object cannot be interpreted as an index.   -  person TheChymera    schedule 14.06.2014
comment
используйте .rx2() с подробными примерами, приведенными здесь:   -  person CT Zhu    schedule 14.06.2014
comment
Мне очень, очень неясно, как работает RPy, но как один из сопровождающих lme4 я имею некоторое представление о том, как это работает в R. Если вы хотите получить объект, содержащий материал, который будет напечатан с помощью (например) summary.merMod вы можете сделать capture.output(summary(fitted_model)) в R...   -  person Ben Bolker    schedule 14.06.2014
comment
@БенБолкер +1. Разве R не является полностью нелогичным для этих вещей...   -  person lgautier    schedule 14.06.2014
comment
Я так не думаю... Я думаю, проблема в том, что (1) R и Python работают по-разному, и каждый привыкает к одному или другому и (2) есть дополнительные трения на интерфейсе .   -  person Ben Bolker    schedule 14.06.2014
comment
Большое спасибо за ваш совет, но я думаю, что rx2() это то, что я искал. Незначительные проблемы с форматированием и типом переменных, которые остаются нерешенными, насколько я могу судить, связаны исключительно с RPy (см. комментарии к ответу).   -  person TheChymera    schedule 14.06.2014
comment
@TheChymera, см. редактирование. То, что вы просили, не так уж сложно получить.   -  person CT Zhu    schedule 14.06.2014


Ответы (1)


Правильный способ - использовать метод .rx2(), несколько различных способов его использования:

In [43]:

print test2_sum.names
Unable to unlink tempfile c:\docume~1\x60t\locals~1\temp\tmpnhw4n4
 [1] "methTitle"    "objClass"     "devcomp"      "isLmer"       "useScale"    

 [6] "logLik"       "family"       "link"         "ngrps"        "coefficients"

[11] "sigma"        "vcov"         "varcor"       "AICtab"       "call"        

[16] "residuals"   

In [44]:

print test2_sum.rx2('vcov') # to access R type print out
Unable to unlink tempfile c:\docume~1\x60t\locals~1\temp\tmpebn3f1
4 x 4 Matrix of class "dpoMatrix"

                      (Intercept)     CoIhard  measurement CoIhard:measurement

(Intercept)         93253.4275120 -80.6588422 -0.503069702         0.503069702

CoIhard               -80.6588422 161.3176844  0.503069702        -1.006139404

measurement            -0.5030697   0.5030697  0.004192248        -0.004192248

CoIhard:measurement     0.5030697  -1.0061394 -0.004192248         0.008384495

In [45]:

print test2_sum.rx2('varcor') # to access R type print out
Unable to unlink tempfile c:\docume~1\x60t\locals~1\temp\tmpcad6ld
 Groups   Name        Std.Dev.

 ID       (Intercept) 1057.39 

 Residual              242.24 

In [46]:

list(test2_sum.rx2('varcor')) # to get the values
Out[46]:
[<Matrix - Python:0x0782CEB8 / R:0x0E97FB28>
[1118073.223847]]
In [47]:

list(test2_sum.rx2('varcor')[0]) # to get the values
Out[47]:
[1118073.2238471208]

Вы избавитесь от большинства вещей, пропустив calls и residuals, попробуйте:

for i, v in enumerate(list(test2_sum.names)):
    if v not in ['call', 'residuals']:
        print '%s========================================================='%i, v
        print test2_sum.rx2(v)

Дополнительное редактирование:

Я думаю, что лучшим подходом для доступа к результату tTable из lme4 (используя rpy2) было бы преобразовать его в pandas DataFrame:

In [73]:

print com.convert_robj(test2_sum.rx2('tTable'))
                           Value   Std.Error    DF    t-value       p-value
(Intercept)          2480.515542  305.374210  5769   8.122872  5.521357e-16
CoIhard               -90.840336   12.701090  5769  -7.152169  9.602962e-13
measurement            -0.288709    0.064748  5769  -4.458998  8.390496e-06
CoIhard:measurement     1.049136    0.091567  5769  11.457595  4.546122e-30

[4 rows x 5 columns]

Вывод print не совсем совпадает с выводом R, но это очень легко сделать:

In [87]:

print test2_sum.rx2('tTable').__str__().replace('\r\n\r\n', '\n')

                           Value    Std.Error   DF   t-value      p-value
(Intercept)         2480.5155423 305.37420990 5769  8.122872 5.521357e-16
CoIhard              -90.8403359  12.70108989 5769 -7.152169 9.602962e-13
measurement           -0.2887093   0.06474757 5769 -4.458998 8.390496e-06
CoIhard:measurement    1.0491363   0.09156689 5769 11.457595 4.546122e-30
person CT Zhu    schedule 14.06.2014
comment
Хорошо, это здорово! Но .rx2(), похоже, теряет то небольшое форматирование, которое смог перенести RPy. Есть ли какая-нибудь рабочая альтернатива чему-то вроде print pd.DataFrame(summary.rx2("tTable"))? В качестве альтернативы, могу ли я просто вызывать значения исключительно с именами, а не числовыми индексами (чтобы итеративно создавать свой собственный Pandas DataFrame только с нужными мне значениями) - например, summary.rx2("tTable").rx2("p-value") ? - person TheChymera; 14.06.2014
comment
Для вывода print вы можете получить доступ и изменить __str__, чтобы получить вывод как можно ближе к выводу R. Тип summary.rx2("tTable").rx2("p-value"), о котором вы просили, вполне выполним, если вы преобразуете результат в Pandas DataFrame, но он должен вызываться: com.convert_robj(test2_sum.rx2('tTable'))['p-value'] - person CT Zhu; 14.06.2014
comment
Отлично, вы охватили почти все аспекты того, что я хотел сделать, спасибо! - person TheChymera; 14.06.2014