Как мне запрограммировать тесты на R, чтобы они хорошо печатались? - PullRequest
0 голосов
/ 28 мая 2019

Статистические тесты в R генерируют списки, но затем, когда вы вызываете тест, печать этих списков дает специальную удобную структуру, чтобы помочь читателю.Чтобы понять, о чем я говорю, рассмотрим пример, где вы используете функцию t.test в пакете stats.

#Run a T-test on some example data
X <- c(30, 32, 40, 28, 29, 35, 30, 34, 31, 39);
Y <- c(19, 20, 44, 45, 8, 29, 26, 59, 35, 50);
TEST <- stats::t.test(X,Y);

#Show structure of the TEST object
str(TEST);
List of 9
 $ statistic  : Named num -0.134
  ..- attr(*, "names")= chr "t"
 $ parameter  : Named num 10.2
  ..- attr(*, "names")= chr "df"
 $ p.value    : num 0.896
 $ conf.int   : num [1:2] -12.3 10.9
  ..- attr(*, "conf.level")= num 0.95
 $ estimate   : Named num [1:2] 32.8 33.5
  ..- attr(*, "names")= chr [1:2] "mean of x" "mean of y"
 $ null.value : Named num 0
  ..- attr(*, "names")= chr "difference in means"
 $ alternative: chr "two.sided"
 $ method     : chr "Welch Two Sample t-test"
 $ data.name  : chr "X and Y"
 - attr(*, "class")= chr "htest"

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

#Print the TEST object
TEST;

        Welch Two Sample t-test

data:  X and Y
t = -0.13444, df = 10.204, p-value = 0.8957
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -12.27046  10.87046
sample estimates:
mean of x mean of y 
     32.8      33.5 

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


Мои вопросы: Почему R выводит вывод списка TEST таким специальным способом?Если я создаю список выходных данных статистического теста (например, как указано выше), как я могу настроить объект для печати таким образом?

Ответы [ 2 ]

3 голосов
/ 28 мая 2019

Используйте один из приведенных ниже методов, который наилучшим образом соответствует вашим потребностям.

X <- c(30, 32, 40, 28, 29, 35, 30, 34, 31, 39)
Y <- c(19, 20, 44, 45, 8, 29, 26, 59, 35, 50)
TEST <- stats::t.test(X,Y)

#default; printing data of htest class
print(TEST) 

#printing every element of the list
lapply(TEST, print) 
print.listof(TEST)

#printing the results as a dataframe
broom::tidy(TEST) #output of this one is included just for illustration


    # A tibble: 1 x 10
  estimate estimate1 estimate2 statistic p.value parameter conf.low conf.high method                  alternative
     <dbl>     <dbl>     <dbl>     <dbl>   <dbl>     <dbl>    <dbl>     <dbl> <chr>                   <chr>      
1     -0.7      32.8      33.5    -0.134   0.896      10.2    -12.3      10.9 Welch Two Sample t-test two.sided 

Для ответа на следующий вопрос OP:

«Каждый» класс данных имеет метод печати.Как я обрисовал в своем ответе, функция print смотрит на TEST и, поскольку это класс htest, она использует print.htest.

class(TEST)
# [1] "htest"

head(methods(print))
# [1] "print.acf"         "print.AES"         "print.all_vars"    "print.anova"
# [5] "print.anova.lme"   "print.ansi_string"

В моем недавно открытом сеансе R у меня есть 185 различных методов.По мере загрузки библиотек число будет увеличиваться.

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

0 голосов
/ 28 мая 2019

Этот ответ составлен из полезных комментариев и ответов других пользователей, но я хотел бы дать здесь подробный ответ, чтобы сделать вещи более явными, в интересах пользователей, которые еще не знакомы с некоторыми из этих проблем.Объект, созданный функцией t.test, является объектом класса htest, и этот тип объекта имеет специальный метод печати с настройкой print.htest в глобальномсреда.Этот метод печати извлекает информацию из списка, но печатает ее в удобной для пользователя форме, которую вы видите в выводе вопроса.

Если вы хотите повторить этот тип печати для нового статистического теста, который выВы сами программируете, тогда вам нужно будет структурировать ваш новый тест так, чтобы он выводил объект htest с необходимыми элементами списка и требуемым классом.Вот пример из другого ответа , где тест гипотезы, изложенный в Tarone (1979) , запрограммирован как htest объект:

Tarone.test <- function(N, M) {

    #Check validity of inputs
    if(any(M > N)) { stop("Error: Observed count value exceeds binomial trials"); }

    #Set hypothesis test objects
    method      <- "Tarone's Z test";
    alternative <- "greater";
    null.value  <- 0;
    attr(null.value, "names") <- "dispersion parameter";
    data.name   <- paste0(deparse(substitute(M)), " successes from ", 
                          deparse(substitute(N)), " counts");

    #Calculate test statistics
    estimate    <- sum(M)/sum(N);
    attr(estimate, "names") <- "proportion parameter";

    S           <- sum((M - N*estimate)^2/(estimate*(1 - estimate)));
    statistic   <- (S - sum(N))/sqrt(2*sum(N*(N-1))); 
    attr(statistic, "names") <- "z";

    p.value     <- 2*pnorm(-abs(statistic), 0, 1);
    attr(p.value, "names") <- NULL;

    #Create htest object
    TEST        <- list(statistic = statistic, p.value = p.value, estimate = estimate, 
                        null.value = null.value, alternative = alternative, 
                        method = method, data.name = data.name);
    class(TEST) <- "htest";

    TEST; }

В этомНапример, функция вычисляет все необходимые элементы объекта htest, а затем создает этот объект в виде списка с этим классом.Важно включить в код команду class(TEST) <- "htest", чтобы создаваемый объект был не просто обычным списком.Включение этой команды гарантирует, что выходной объект имеет правильный класс, и поэтому он будет печатать в удобной для пользователя форме.Чтобы увидеть это, мы можем сгенерировать некоторые данные и применить тест:

#Generate example data
N <- c(30, 32, 40, 28, 29, 35, 30, 34, 31, 39);
M <- c( 9, 10, 22, 15,  8, 19, 16, 19, 15, 10);

#Apply Tarone's test to the example data
TEST <- Tarone.test(N, M);
TEST;

        Tarone's Z test

data:  M successes from N counts
z = 2.5988, p-value = 0.009355
alternative hypothesis: true dispersion parameter is greater than 0
sample estimates:
proportion parameter 
           0.4359756

Здесь мы видим, что наша вновь созданная функция тестирования гипотез дает нам вывод, который имеет дружественную для пользователя структуру, аналогичную t.test,В этом примере мы дали разные имена методу тестирования и элементам теста, и они появляются в описательном выводе при печати. ​​

...