Как запрограммировать тесты в R, чтобы они хорошо печатались?

Статистические тесты в 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 таким особым образом? Если я создам список выходных данных статистического теста (например, как показано выше), как я могу настроить объект для печати таким образом?

Посмотрите на класс результата, а затем на «методы (печать)».

IRTFM 28.05.2019 03:05
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
743
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

Спасибо за Ваш ответ. Хотя это, безусловно, очень интересно, это не объясняет, почему R печатает Т-тест так, как он это делает по умолчанию, или как это можно эмулировать в другом списке.

Ben 28.05.2019 04:00

@ Бен Так и есть. «Каждый» класс данных имеет метод печати. Как я указал в своем ответе, print смотрит на TEST и, поскольку это класс htest, он использует print.htest. Вы можете проверить класс ваших данных class(TEST) и увидеть различные способы печати methods(print). Если вы хотите копнуть глубже, вам нужно посмотреть исходный код print, который можно найти здесь: github.com/wch/r-source/blob/trunk/src/library/base/R/print.‌​R

M-- 28.05.2019 04:17
Ответ принят как подходящий

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

Если вы хотите воспроизвести этот тип печати для нового статистического теста, который вы программируете самостоятельно, вам нужно будет структурировать свой новый тест так, чтобы он выводил объект htest с требуемыми элементами списка и требуемым классом. Вот пример из другого отвечать, где проверка гипотезы, изложенная в Тароне (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. В этом примере мы дали разные имена методу тестирования и элементам теста, и они появляются в описательных выводах при печати.

Это не мой минус, но я понимаю, почему это так. Вы делаете так называемый пользовательский тест (MY.TEST), который имеет точные переменные (выходные данные), такие как t.test. Разве ты не видишь? Вы только что снова создали t.test, но теперь вместо того, чтобы создавать структуру вывода автоматически, вы помещаете их в htest вручную. Какой в ​​этом смысл? Если вы можете придумать статистический тест, который впоследствии может быть использован в качестве входных данных для вашей функции, не могли бы вы представить его в качестве примера в своем ответе, чтобы избежать дальнейших отрицательных голосов. Честно говоря, я вывернул свою руку, чтобы не нажать на эту стрелку вниз. Ваше здоровье.

M-- 28.05.2019 22:34

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

Ben 29.05.2019 00:54

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

M-- 29.05.2019 00:57

Другие вопросы по теме