Как перебрать все возможные сравнения уровней факторов в R

Рассмотрим следующий кадр данных:

type = c('A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'D', 'D', 'D')
val1 = c(.35, .36, .35, .22, .27, .25, .88, .9, .87, .35, .35, .36)
val2 = c(.35, .35, .37, .40, .42, .46, .9, .91, .82, .36, .36, .36)

df = data.frame (type, val1, val2)

У меня есть четыре категории (называемые типами; A, B, C и D). Три наблюдения каждого типа могут быть усреднены для создания многомерного среднего типа (составленного из средних значений val1 и val2). Я хотел бы сравнить все возможные комбинации типов (AB, AC, AD, BC, BD, CD), используя тест Хотеллинга, чтобы определить, какие типы средств (если таковые имеются) одинаковы. Я мог бы жестко закодировать это как:

a = filter (df, type == "A") [,2:3]
b = filter (df, type == "B") [,2:3]
c = filter (df, type == "C") [,2:3]
d = filter (df, type == "D") [,2:3]

А затем выполните тест T2 Hotelling для каждой указанной пары типов:

library('Hotelling')
hotelling.test(a, b, shrinkage=FALSE)
hotelling.test(b, c, shrinkage=FALSE)
hotelling.test(a, c, shrinkage=FALSE)

#And so on

Это, очевидно, очень неэффективно и непрактично, учитывая, что мой фактический набор данных имеет 55 различных типов. Я знаю, что ответ заключается в циклах, но мне трудно понять, как сказать hotelling.test, чтобы сравнить многовариантные средства val1 / val2 для всех возможных комбинаций типов. Я очень новичок в создании петель и надеялся, что кто-нибудь может указать мне правильное направление.

После сравнения всех типов в идеале я бы смог получить вывод, показывающий пары типов, для которых p-значение теста Хотеллинга было> 0,05, что означает, что эти два типа, вероятно, являются дубликатами. В примере кадра данных типы A и D возвращают значение p> 0,05, тогда как в других сравнениях p <0,05.

Всего 2 ответа


Мы можем использовать combn для создания парных комбинаций, подмножества набора данных и применения функции

library(Hotelling)
outlst <- combn(as.character(unique(df$type)), 2, 
    FUN = function(x) hotelling.test(subset(df, type == x[1], select = -1), 
          subset(df, type == x[2], select = -1)), simplify = FALSE)
names(outlst) <- combn(as.character(unique(df$type)), 2, FUN = paste, collapse = "_")

outlst[1]
#$A_B
#Test stat:  36.013 
#Numerator df:  2 
#Denominator df:  3 
#P-value:  0.007996 

Если вы хотите использовать для циклов:

type = c('A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'D', 'D', 'D')
val1 = c(.35, .36, .35, .22, .27, .25, .88, .9, .87, .35, .35, .36)
val2 = c(.35, .35, .37, .40, .42, .46, .9, .91, .82, .36, .36, .36)

df = data.frame (type, val1, val2)

for (first in unique(df$type)) {
  for (second in unique(df$type)) {
    if (first != second) {
      print(c(first, second))
    }
  }
}

[1] "A" "B"
[1] "A" "C"
[1] "A" "D"
[1] "B" "A"
[1] "B" "C"
[1] "B" "D"
[1] "C" "A"
[1] "C" "B"
[1] "C" "D"
[1] "D" "A"
[1] "D" "B"
[1] "D" "C"

Есть идеи?

10000