Нахождение частот всех возможных пар в R

Я работаю с большим набором данных о лекарствах и реакциях, используя R. На данный момент у меня есть данные, структурированные как очень высокий фрейм данных, в котором перечислены идентификационный номер отчета, название лекарства и сообщенные реакции. Как вы понимаете, между идентификаторами и лекарствами и лекарствами и реакциями существует взаимосвязь "один ко многим".

Имея в виду, что этот набор данных НАМНОГО больше того, что я могу здесь воспроизвести, я хотел бы знать, как найти какие пары лекарств вызывают какие реакции и с какой частотой.

Самое главное, мне интересно, как подойти к такой проблеме. Правильно ли структурированы данные? О каких концепциях или библиотеках мне следует прочитать?

Вот ссылка на некоторые реальные данные: https://www.dropbox.com/s/kzx4mpyytbo9zil/query_result.csv

   ID    DRUG                                REACTION
1  1827  ASPIRIN                           CHEST PAIN
2  1827  CLARINEX                          CHEST PAIN
3  1827  ASPIRIN                                COUGH
4  1827  CLARINEX                               COUGH
5  1827  ASPIRIN                HAEMOGLOBIN DECREASED
6  1827  CLARINEX               HAEMOGLOBIN DECREASED
7  1827  ASPIRIN           NEUTROPHIL COUNT INCREASED
8  1827  CLARINEX          NEUTROPHIL COUNT INCREASED
9  1827  ASPIRIN               PHARYNGOLARYNGEAL PAIN
10 1827  CLARINEX              PHARYNGOLARYNGEAL PAIN
...

В моем маленьком мозгу конечный результат выглядит примерно так ...

    Drug1       Drug2       Reaction            Frequency
1   tylenol     alcohol     hepatic failure     298
2   advil       aleve       bleeding            201 
3   aspirin     advil       renal failure       199
4   docusate    senna       diarrhea            146
5   senna       sudafed     palpitations        121
6   xanax       alcohol     sedation            111
7   clarinex    benadryl    dry mouth           96
...
569 ASPIRIN     CLARINEX    CHEST PAIN          2

Drug1 и Drug2 - это пары наркотиков с самой высокой частотой из всего набора данных. «Пара препаратов» определяется как любая комбинация двух препаратов с одним и тем же идентификатором отчета. Приведенный выше пример выходных данных можно интерпретировать как «строка 1 содержит 298 уникальных идентификаторов отчетов, для которых реакцией является печеночная недостаточность».


person Ryan    schedule 10.08.2014    source источник
comment
возможный дубликат Подсчет уникальных пар категориальных переменных в R   -  person    schedule 10.08.2014
comment
Как вы выбираете наркотик1 и наркотик2? Вы должны показать, как вы хотите, чтобы ASPIRIN и CLARINEX попали в финальную таблицу.   -  person rnso    schedule 10.08.2014
comment
@mso, вопрос обновлен, чтобы ответить на ваши вопросы. Спасибо.   -  person Ryan    schedule 10.08.2014
comment
Это не совсем тот вопрос, который задается в предлагаемом дубликате, Подсчет уникальных пар категориальных переменных в R. Я не просто хочу подсчитывать количество уникальных пар лекарств, я хочу подсчитывать количество пар лекарств + реакций. Во-первых, мне нужно сгенерировать все пары препаратов для данного отчета.   -  person Ryan    schedule 10.08.2014
comment
Пока не ясно. в строке 1 было 298 уникальных идентификаторов отчетов, на которые была указана печеночная недостаточность. как для тиленола, так и для алкоголя? Опишите, пожалуйста, подробно.   -  person rnso    schedule 10.08.2014
comment
Я все еще не понимаю - глядя на вашу репутацию, я предполагаю, что вы не ищете помощи по таким функциям, как unique, как разделить данные (subset, [) и как выполнить цикл / применить это к unique(df$REACTION)? Если это не скорее статистический / концептуальный вопрос, не могли бы вы прояснить вопрос программирования?   -  person Martin    schedule 10.08.2014
comment
В каждом отчете id может быть много наркотиков и много реакций. Я хочу использовать все возможные пары (drug1 + drug2) наркотиков для каждого отчета id, а затем каждые < i> response для каждого отчета id и увеличивает счетчик для любого экземпляра этих трех (frequency). (учитывая, что аспирин + кларинекс - это то же самое, что и кларинекс + аспирин)   -  person Ryan    schedule 10.08.2014
comment
@Martin, Моя репутация основана не на знании R, это точно. Я все еще пытаюсь осмыслить то, что, кажется, является мышлением Р. Концептуальный вопрос заключается в том, должен ли я использовать другой тип данных или по-другому организовывать данные, и вопрос программирования - это именно тот тип вещей, о котором вы упоминаете. Я постараюсь впиться зубами в unique и subset еще немного. Спасибо.   -  person Ryan    schedule 10.08.2014
comment
каждый идентификатор отчета: unique(df$ID) - ›просмотреть или использовать функцию применения   -  person Martin    schedule 10.08.2014
comment
Кажется, что ваши данные - это полное соединение двух данных: какие лекарства принимал пациент и какие реакции у него были. Если это так, может быть, вы согласитесь, что это пустая трата времени. Вы можете просто сохранить его в двух именованных списках. На мой взгляд, с ним также было бы легче работать.   -  person flodel    schedule 10.08.2014
comment
Эти данные должны быть получены из ISR, DRUGNAME, OUTC_CODE, PT файла csv? OUTC_CODE - это CA во всем файле. Является ли ISR файла csv таким же, как ID и PT, таким же, как «реакция»?   -  person rnso    schedule 10.08.2014
comment
@rnso Да. ISR = ID, НАЗВАНИЕ ПРЕПАРАТА = ПРЕПАРАТ, PT = РЕАКЦИЯ. OUTC_CODE не обязательно имеет отношение к вопросу. Это фильтр, который я использовал для получения информации из более крупного набора данных.   -  person Ryan    schedule 10.08.2014


Ответы (1)


Хорошо, я пытаюсь ответить - надеюсь, я правильно понял вопрос. Код скорее предназначен для того, чтобы дать некоторые идеи, чем быть элегантным / окончательным.
Обратите внимание: я намеренно использовал циклы for вместо возможных функций векторизации / применения, чтобы упростить понимание (те, кто знаком с функциями применения, будут также выполните цикл for ;-)).
Обратите внимание на 2: поскольку у меня есть только крошечный фрагмент данных, я не смог протестировать код для всего набора данных!
EDIT < / strong>: столбцы на основе приведенного выше примера - возможно, отличаются от данных csv.

Ключевые моменты:

  • unique, [ и т. Д.
  • utils::combn, чтобы получить комбинации
  • сумма (значения ЛОЖЬ / ИСТИНА) для подсчета

Надеюсь, это поможет!

require(utils)

df <- read.table(header=TRUE, 
text="LINE ID DRUG REACTION
1 1827 ASPIRIN CHEST_PAIN
2 1827 CLARINEX CHEST_PAIN
3 1827 ASPIRIN COUGH
4 1827 CLARINEX COUGH
5 1827 ASPIRIN HAEMOGLOBIN_DECREASED
6 1827 CLARINEX HAEMOGLOBIN_DECREASED
7 1827 ASPIRIN NEUTROPHIL_COUNT_INCREASED
8 1827 CLARINEX NEUTROPHIL_COUNT_INCREASED
9 1827 ASPIRIN PHARYNGOLARYNGEAL_PAIN
10 1827 CLARINEX PHARYNGOLARYNGEAL_PAIN")

# temporary object to collect if a combination is present
Results <- data.frame(Drug1=NA, Drug2=NA, Reaction=NA, Reaction.occurs=NA)
n=1 # start first line in Results object

#  walk through each ID ... 
for (ID in unique(df$ID)) { 

  # ... and each possible pair of drugs within a (report) ID ...
  drug.pairs <- utils::combn(x=unique(df[df$ID == ID, "DRUG"]), m=2) # the columns 
  for (ii in 1:ncol(drug.pairs)) {

    # ... and each reaction ...
    for (reaction in unique(df$REACTION)) {
      Results[n, "Drug1"] <- drug.pairs[1,ii]
      Results[n, "Drug2"] <- drug.pairs[2,ii]
      Results[n, "Reaction"] <- reaction
      Results[n, "Reaction.occurs"] <- drug.pairs[1,ii] %in% df[df$REACTION == reaction & df$ID == ID, "DRUG"] &
        drug.pairs[2,ii] %in% df[df$REACTION == reaction & df$ID == ID, "DRUG"]
      n <- n+1
    }
  }
}

head(Results)

# then find the unique Drug1 - Drug2 -Reaction combinations, and count the TRUE values:
(Results[!duplicated(Results[,1:3]), ][,1:3])
(unique(Results[, 1:3]))

# Results2 contains only the unique combinations
Results2 <- Results[!duplicated(Results[,1:3]), ][,1:3]

# calculatethe frequencies
for (i in 1:nrow(Results2)) {
  Results2[i, "Frequency"] <- sum(Results[Results$Drug1 == Results2[i, "Drug1"] & 
                                            Results$Drug2 == Results2[i, "Drug2"] & 
                                            Results$Reaction == Results2[i, "Reaction"], ]$Reaction.occurs)
}

Results2
# --- end ----

дает:

    Drug1    Drug2                   Reaction Frequency
1 ASPIRIN CLARINEX                 CHEST_PAIN         1
2 ASPIRIN CLARINEX                      COUGH         1
3 ASPIRIN CLARINEX      HAEMOGLOBIN_DECREASED         1
4 ASPIRIN CLARINEX NEUTROPHIL_COUNT_INCREASED         1
5 ASPIRIN CLARINEX     PHARYNGOLARYNGEAL_PAIN         1
person Martin    schedule 10.08.2014
comment
Я тестировал приведенный выше код с данными из файла csv: только 3 элемента имеют частоту 1, все остальные частоты равны 0: ЛАМИВУДИН + СТАВУДИН: ВОЗДЕЙСТВИЕ НАРКОТИКОВ ВО ВРЕМЯ БЕРЕМЕННОСТИ 1 ЛАМИВУДИН + СТАВУДИН: ДИСПЛАЗИЯ БЕДРА 1 ЛАМИВУДИН + СТАВУДИН: МАТЕРИНСКИЕ НАРКОТИКИ 1 Я добавил + ,: и для пояснения). - person rnso; 10.08.2014
comment
Нет точно, что я буду использовать в конечном итоге, но методы и функции дали мне отличную отправную точку, чтобы научиться формулировать эту проблему. Функции мертвые. Спасибо за обучение! - person Ryan; 12.08.2014