Тест Крускала-Уоллиса: создать функцию lapply для подмножества data.frame?

У меня есть набор данных значений (val) сгруппированы по нескольким категориям (distance & phase). Я хотел бы проверить каждую категорию Kruskal-Wallis test, где val зависимая переменная, distance является фактором, и phase разделить мои данные на 3 группы.

Поэтому мне нужно указать подмножество данных в тесте Крускала-Уоллиса, а затем применить тест к каждой из групп. НО, я не могу заставить свою подмножество работать!

В справке R указано, что subset является an optional vector specifying a subset of observations to be used. Но как правильно поставить это на мой lapply функционировать?

Мои фиктивные данные:

# create data
val<-runif(60, min = 0, max = 100)
distance<-floor(runif(60, min=1, max=3))
phase<-rep(c("a", "b", "c"), 20)

df<-data.frame(val, distance, phase)

# get unique groups
ii<-unique(df$phase)

# get basic statistics per group
aggregate(val ~ distance + phase, df, mean)

# run Kruskal test, specify the subset
kruskal.test(df$val ~df$distance,
             subset = phase == "c")

Это хорошо работает, поэтому мое подмножество должно быть правильно задано как вектор. Но как использовать это в lapply функционировать?

# DOES not work!!
lapply(ii, kruskal.test(df$val ~ df$distance,
                        subset = df$phase == as.character(ii))) 

Моя общая цель - создать функцию из kruskal.testи сохранить всю статистику для каждой группы в одну таблицу.

Вся помощь высоко ценится.

2 ответа

Решение

Обычно вы начинаете с splitтинг, а затем lapplyING.

Что-то вроде

lapply(split(df, df$phase), function(d) { kruskal.test(val ~ distance, data=d) })

выдаст список, проиндексированный по фазе, результатов kruskal.test.

Ваше окончательное выражение не работает, потому что lapply ожидает функцию и применение kruskal.test не приводит к функции, это приводит к результату выполнения этого теста. Если вы окружите его определением функции с индексом, то это будет работать, просто будьте немного менее идиоматичны.

lapply(ii, function(i) { kruskal.test(df$val ~ df$distance, subset=df$phase==i )})

Хотя уже поздно, это может помочь кому-то с той же проблемой. Итак, я ставлю ответ, реализованный с использованием tidyverseи пакеты. rstatixпакет, который «предоставляет простую и интуитивно понятную структуру, удобную для конвейера, согласующуюся с философией дизайна« tidyverse »для выполнения основных статистических тестов».

      library(rstatix)
library(tidyverse)

df %>% 
  group_by(phase) %>% 
  kruskal_test(val ~ distance)

Выход

      # A tibble: 3 x 7
  phase .y.       n statistic    df     p method        
* <chr> <chr> <int>     <dbl> <int> <dbl> <chr>         
1 a     val      20    0.230      1 0.631 Kruskal-Wallis
2 b     val      20    0.0229     1 0.88  Kruskal-Wallis
3 c     val      20    0.322      1 0.570 Kruskal-Wallis

то же, что и предоставлено пользователем @user295691. Данные

      df = structure(list(val = c(93.8056977232918, 31.0681172646582, 40.5262873973697, 
47.6368983509019, 65.23181500379, 64.4571609096602, 10.3301600087434, 
90.4661140637472, 41.2359046051279, 28.3357713604346, 49.8977075796574, 
10.8744730940089, 5.31001624185592, 71.9248640118167, 99.0267782937735, 
73.7928744405508, 3.31214582547545, 40.2693636715412, 27.6980920461938, 
79.501334275119, 60.5167196830735, 89.9171086261049, 87.4633299885318, 
43.1893823202699, 91.1248738644645, 99.755659350194, 7.25280269980431, 
96.957387868315, 75.0860505970195, 52.3794749286026, 26.6221587313339, 
52.5518182432279, 24.1361060412601, 49.5364486705512, 65.5214034719393, 
38.9469220302999, 0.687191751785576, 19.3090825574473, 19.6511475136504, 
25.5966754630208, 7.33999472577125, 33.9820940745994, 50.3751677693799, 
10.811762069352, 17.2359711956233, 53.958406439051, 64.2723652534187, 
92.7404976682737, 26.824192632921, 30.0975760444999, 52.0105463219807, 
74.4495407678187, 56.0636054025963, 91.891074879095, 14.0827904455364, 
59.3607738381252, 66.5170294465497, 24.1726311156526, 83.0881901318207, 
35.5380675755441), distance = c(2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 
2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 
1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 2, 1, 1, 2, 2, 2, 2, 1, 
1, 2, 1, 1, 2, 2, 2, 2), phase = c("a", "b", "c", "a", "b", "c", 
"a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", 
"b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", 
"c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", 
"a", "b", "c", "a", "b", "c", "a", "b", "c", "a", "b", "c", "a", 
"b", "c")), class = "data.frame", row.names = c(NA, -60L))
Другие вопросы по тегам