#r #function #matrix #contrast
#r #функция #матрица #контраст
Вопрос:
У меня есть следующий тип данных, означающий комбинацию факторов
P1 <- c("a", "a", "a", "a", "b", "b", "b", "c", "c", "d")
P2 <- c("a", "b", "c", "d", "b", "c", "d", "c", "d", "d")
myfactors <- data.frame(P1, P2)
P1 P2
1 a a
2 a b
3 a c
4 a d
5 b b
6 b c
7 b d
8 c c
9 c d
10 d d
В реальном word коэффициентами может быть любое число, я пытаюсь написать функцию, которая может быть применима к любому уровню коэффициентов. Я хочу установить контрасты для всех комбинаций, доступных в наборе данных. например, в этом наборе данных a-b, a-c, a-d, b-c, b-d, c-d. Здесь действует правило контраста.
for example for "a-b" is if P1 = P2 = a or b the coefficient = -1,
if P1=a, P2= b or P1= b, P2 = a, the coefficient = 2,
else coefficient = 0
Выходная матрица коэффициентов будет выглядеть следующим образом:
P1 P2 a-b a-c a-d b-c b-d c-d
a a -1 -1 -1 0 0 0
a b 2 0 0 0 0 0
a c 0 2 0 0 0 0
a d 0 0 2 0 0 0
b b 1 0 0 -1 -1 0
b c 0 0 0 2 0 0
b d 0 0 0 0 2 0
c c 0 1 0 0 0 -1
c d 0 0 0 -1 0 2
d d 0 0 -1 0 -1 -1
Поскольку функция, о которой я думаю, является гибкой, если я применю ее к следующему набору данных,
P1 <- c("CI", "CI", "CI", "CD", "CD", "CK", "CK")
P2 <- c("CI", "CD", "CK", "CD", "CK", "CK", "CI")
mydf2 <- data.frame(P1, P2)
mydf2
P1 P2
1 CI CI
2 CI CD
3 CI CK
4 CD CD
5 CD CK
6 CK CK
7 CK CI
Ожидаемая матрица коэффициентов для этого фрейма данных равна:
P1 P2 CI-CD CI-CK CD-CK CK-CI
CI CI -1 -1 0 -1
CI CD 2 0 0 0
CI CK 0 2 0 0
CD CD -1 0 -1 0
CD CK 0 0 2 0
CK CK 0 -1 -1 -1
CK CI 0 0 0 2
Я перепробовал несколько способов, но не смог прийти к успешной программе.
ПРАВКИ:
(1) Я не тестирую все возможные комбинации, тестируются комбинации, которые появляются только в P1 и P2
(2) Я намерен разработать решение не только для этого экземпляра, но и общего применения. например, фрейм данных myfactors выше.
Ответ №1:
Вы не указали причину вашего конкретного выбора из 6 упорядоченных комбинаций значений P1 и P2, поэтому я просто пробежался по ним всем:
combos <- cbind( combn(unique(c(P2, P1)), 2), combn(unique(c(P2, P1)), 2)[2:1, ])
combos
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] "CI" "CI" "CD" "CD" "CK" "CK"
[2,] "CD" "CK" "CK" "CI" "CI" "CD"
Когда я проходил логику, мне показалось более компактным протестировать условия 1) и 2) и просто использовать логическую математику для возврата результатов. Если оба условия неверны, вы получаете 0. Я проверил записи, которые не соответствуют вашим, и я думаю, что ваша конструкция была неправильной в некоторых местах. У вас 0 в строке 7 «CI-CK», и я думаю, что ответ по вашим правилам должен быть 2.:
sapply(1:ncol(combos), function(x) with( mydf2,
2*( (P1==combos[1,x] amp; P2 == combos[2,x]) | (P2==combos[1,x] amp; P1 == combos[2,x])) -
(P1 == P2 amp; P1 %in% combos[,x]) ) )
#---------------
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] -1 -1 0 -1 -1 0
[2,] 2 0 0 2 0 0
[3,] 0 2 0 0 2 0
[4,] -1 0 -1 -1 0 -1
[5,] 0 0 2 0 0 2
[6,] 0 -1 -1 0 -1 -1
[7,] 0 2 0 0 2 0
#------------------
mydf2[ , 3:8] <- sapply(1:ncol(combos), function(x) with( mydf2,
2*( (P1==combos[1,x] amp; P2 == combos[2,x]) | (P2==combos[1,x] amp; P1 == combos[2,x])) -
(P1 == P2 amp; P1 %in% combos[,x]) ) )
mydf2
#-----------------
P1 P2 CI-CD CI-CK CD-CK CD-CI CK-CI CK-CD
1 CI CI -1 -1 0 -1 -1 0
2 CI CD 2 0 0 2 0 0
3 CI CK 0 2 0 0 2 0
4 CD CD -1 0 -1 -1 0 -1
5 CD CK 0 0 2 0 0 2
6 CK CK 0 -1 -1 0 -1 -1
7 CK CI 0 2 0 0 2 0
Комментарии:
1. отлично, спасибо …. две проблемы (1) относительно вашего вопроса, почему не все возможные комбинации? Мне не нужны все возможные комбинации между этими двумя факторами (поскольку не все комбинации тестируются — в данном случае тестируемая комбинация, P1 и P2 идентичны, только предоставляются, поэтому при сравнении CK-CD вы не получили «2», поскольку не тестировалась комбинация CK-CD (b) combochk <- data.frame(mydf2, list(NA, NA, NA, NA, NA, NA)), как мы можем автоматизировать количество NAS, поскольку я хочу, чтобы эта функция имеет общее применение (например, myfactors df отличается), здесь мы знаем точно 6 протестированных комбинаций
2. Я позже понял, что
combochk <- data.frame(mydf2, list(NA,NA, NA, NA,NA, NA))
код не нужен. Пока вы настраиваетеcombos
матрицу по своему вкусу, вы можете просто использоватьmydf2[, 3:(ncol(combos) 2)] <- sapply(.....)
. Я отредактировал код, чтобы сделать его менее запутанным.3. вы правы, CK-CI или CI-CK должно быть 2, если я применяю обратное правило … но я ранее ошибался, что мне действительно нужно обратное правило.. путем удаления из нее условия «или P1= b, P2 = a» … не реализованного ранее … Спасибо