t.test: создать функцию lapply для нескольких уровней группировки - PullRequest
0 голосов
/ 19 марта 2019

Я пытаюсь создать функцию lapply для запуска нескольких t.test с для нескольких уровней группировки. Я сталкивался с таким вопросом: Тест Крускала-Уоллиса: создать функцию lapply для подмножества data.frame? , но они пытались сгруппировать только по одной переменной (phase). Я хотел бы добавить еще один уровень группировки color, где мой iv distance, а dv val сгруппированы по color затем phase.

# create data
val<-runif(60, min = 0, max = 100)
distance<-floor(runif(60, min=1, max=3))
phase<-rep(c("a", "b", "c"), 20)
color<-rep(c("red", "blue","green","yellow","purple"), 12)

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

Их ответ для группировки по phase был

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

Тем не менее, он не учитывает другой уровень (color) для группировки. Возможно, я подхожу к этому неправильно, поэтому я ценю любую помощь.

1 Ответ

2 голосов
/ 19 марта 2019

Просто включите list() внутри split в нужных столбцах. Однако для вашего примера это приведет к ошибке, поскольку некоторые группы имеют одинаковые значения distance .

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

Ошибка в kruskal.test.default (c (76.6759299905971, 3.11371604911983, 17.6471394719556,: все наблюдения находятся в одной группе

Следовательно, рассмотрим перенос в tryCatch, чтобы вернуть NA или любой другой объект для этих групп проблем:

lapply(split(df, list(df$color, df$phase)), function(d) {
    tryCatch({ kruskal.test(val ~ distance, data=d) },
             error = function(e) NA)
})

Кстати, рассмотрим by (объектно-ориентированную оболочку для tapply и часто пропускаемый член семейства apply) вместо того, чтобы вкладывать split в lapply:

by(df, df[c("color", "phase")], function(d) {
    tryCatch({ kruskal.test(val ~ distance, data=d) },
             error = function(e) NA)
})
...