Надежная 2-сторонняя ANOVA в Python

#python #r #statistics #rpy2

#питон #r #Статистика #rpy2

Вопрос:

Мне нужно запустить надежный ANOVA из Python. Функция, которую я хочу использовать t2way , взята из R-пакета WRS2. Я попробовал с помощью r2py, но я застрял с ошибкой:

 >>> import rpy2.robjects.packages as rpackages
>>> from rpy2.robjects import pandas2ri
>>> pandas2ri.activate()
>>> df = pd.read_csv("https://github.com/lawrence009/dsur/raw/master/data/goggles.csv")
>>> rdf = pandas2ri.py2rpy(df)
>>> WRS2 = rpackages.importr('WRS2')
>>> WRS2.t2way("attractiveness ~ gender*alcohol", data = rdf)

RRuntimeError: Error in x[[grp[i]]] : 
  attempt to select less than one element in get1index
 

Я ищу либо способ заставить это работать с rpy2, либо (что еще лучше) порт WRS2 для среды python. Любая помощь будет высоко оценена.

Ответ №1:

Если проблема связана со столбцами в фрейме данных, которые не являются факторами (как предложено в другом ответе), преобразовать их в факторы довольно просто:

 rdf = pandas2ri.py2rpy(df)

base = importr('base')
import rpy2.robjects as ro

for cn in ('alcohol', 'gender'):
    i = rdf.colnames.index(cn)
    rdf[i] = base.as_factor(rdf[i])
    # We could also do it with
    # rdf[i] = ro.FactorVector(rdf[i])
 

На всякий случай рекомендуется создать объект формулы R. Некоторые функции R будут принимать строки и предполагать, что они являются формулами, но это зависит от автора пакета и не всегда так.

 WRS2.t2way(ro.Formula('attractiveness ~ gender*alcohol'), data = rdf)
 

Ответ №2:

вот мое конкретное решение этой проблемы. В самом начале первая проблема в R заключается в том, что при импорте фрейма данных вам необходимо изменить тип столбца alcohol и gender как.factor.

в R сценарий будет выглядеть следующим образом:

 library(WRS2)
df <- read.csv2("https://github.com/lawrence009/dsur/raw/master/data/goggles.csv",header = TRUE, sep=',')
df[ , c('attractiveness')] <- as.numeric(df[ , c('attractiveness')])
df[ , c('alcohol')] <- as.factor(df[ , c('alcohol')])
df[ , c('gender')] <- as.factor(df[ , c('gender')])
t2way(attractiveness ~ gender*alcohol, data = df)
 

Хотя в python я не нашел способа изменить тип данных столбца, но я пришел с этим решением:
Сначала вам нужно создать файл .R с именем my_t2way.R, который содержит:

 my_t2way <- function(df1){
    library(WRS2)
    df <- read.csv2(df1,header = TRUE, sep=',')
    df[ , c('attractiveness')] <- as.numeric(df[ , c('attractiveness')])
    df[ , c('alcohol')] <- as.factor(df[ , c('alcohol')])
    df[ , c('gender')] <- as.factor(df[ , c('gender')])
    f <- t2way(attractiveness ~ gender*alcohol, data = df) 
    df1 = data.frame(factor=c('gender','alcohol','gender:alcohol'),
                     value = c(f$Qa,f$Qb,f$Qab),
                    p.value = c(f$A.p.value,f$B.p.value,f$AB.p.value))
    return(df1)
}
 

И затем вы можете запустить следующие команды из python

 import pandas as pd
import rpy2.robjects as robjects
from rpy2.robjects import pandas2ri# Defining the R script and loading the instance in Python
pandas2ri.activate()

r = robjects.r
r['source']('my_t2way.R')# Loading the function we have defined in R.
my_t2way_r = robjects.globalenv['my_t2way']# Reading and processing data
df1 = "https://github.com/lawrence009/dsur/raw/master/data/goggles.csv"
df_result_r = my_t2way_r(df1)
 

Конечно, это решение работает только для этого конкретного случая, но я думаю, что его можно легко расширить на другие фреймы данных.