R: цикл / функция для создания матрицы для сравнения (контрасты) - PullRequest
2 голосов
/ 06 ноября 2011

У меня есть следующий тип данных, означает сочетание факторов

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

Фактически, факторами может быть любое число, я пытаюсь написать функцию, которая может быть применима к любому уровню факторов. Я хочу установить контрастность всех комбинаций, доступных в наборе данных. например, в этом наборе данных 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 dataframe выше.

1 Ответ

5 голосов
/ 06 ноября 2011

Вы не указали причину для своего конкретного выбора 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 в строке "CI-CK" 7, и я думаю, что ответ по вашим правилам должен быть 2.:

sapply(1:ncol(combos), function(x) with( mydf2,  
      2*( (P1==combos[1,x] & P2 == combos[2,x]) | (P2==combos[1,x] & P1 == combos[2,x])) - 
       (P1 == P2 & 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] & P2 == combos[2,x]) | (P2==combos[1,x] & P1 == combos[2,x])) - 
       (P1 == P2 & 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...