R: Извлечение строк из одного фрейма данных на основе имен столбцов, совпадающих со значениями из другого фрейма данных - PullRequest
0 голосов
/ 17 июня 2019

Я хотел бы знать, как извлечь значения в одном столбце фрейма данных (фрейм данных A) на основе определенных имен столбцов в фрейме данных A, содержащем значения нескольких столбцов из другого фрейма данных (кадр данных B) .

Более конкретно. У меня есть два кадра данных:

Фрейм данных A содержит комбинации врожденных дефектов. Каждая строка представляет собой отдельную комбинацию, а каждый столбец - номер дефекта, включенного в эту комбинацию.

# Combinations data frame 
combos <- data.frame("combo_no"=c(1:4),
                     "Defect_A" = c(1,1,1,1),
                     "Defect_B" = c(3,2,3,4),
                     "Defect_C" = c(4,4,NA,7),
                     "Defect_D" = c(5,5,NA,8),
                     "Defect_E" = c(6,6,NA,NA))

Фрейм данных B содержит отдельные случаи. Первый столбец имеет уникальный идентификатор (CASE_ID). Остальные столбцы - это число конкретных врожденных дефектов, где «1» означает «врожденный дефект присутствует» и «0» означает «не присутствует».

# Cases data set 
set.seed(99)
CASE_ID = c(1001:1005)
case1 = sample(0:1, 10, replace=TRUE)  
case2 = sample(0:1, 10, replace=TRUE)  
case3 = sample(0:1, 10, replace=TRUE)  
case4 = sample(0:1, 10, replace=TRUE)  
case5 = sample(0:1, 10, replace=TRUE)  
def<-data.frame(rbind(case1, case2, case3, case4, case5))
colnames(def)<- c(1:10)
cases<-cbind(CASE_ID,def)

Желаемый результат: Я хотел бы получить список CASE_ID из фрейма данных A, которые имеют комбинацию врожденных дефектов из фрейма данных B. Я также хотел бы указать, какая комбинация присутствует. В идеале вывод должен выглядеть следующим образом:

# Desired Output
output <- data.frame("CASE_ID" = c(1002,1003),
                     "combo_no" = c(3,1))

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 17 июня 2019

Вот решение, длинное для того, чтобы комментировать его шаг за шагом:

### my random generated cases DF:
cases
      CASE_ID 1 2 3 4 5 6 7 8 9 10
case1    1001 1 0 1 1 1 1 1 0 0  0
case2    1002 1 1 0 1 1 1 0 0 0  0
case3    1003 0 0 1 1 1 0 0 1 0  0
case4    1004 1 0 0 1 0 0 1 1 1  1
case5    1005 1 0 1 1 0 1 0 0 1  0
### initialize vectors to store found results
found_combos <- vector(); found_patients <- vector();
### open loop on combos rows
for (i in 1:nrow(combos)) {
  ### open empty vector to fill with the numbers that compose the defect
  defect_numbers <- vector()
  ### open loop on column and take the numbers
  for (col in colnames(combos)[2:length(colnames(combos))]) {
    number <- combos[i, col]
    if ( !is.na(number) ) defect_numbers <- append(defect_numbers, number)
  }
  ### sort the vector to avoid mismatch based on order
  defect_numbers <- sort( defect_numbers )
  ### open loop on patients table
  for ( pz in 1:nrow(cases) ) {
    pz_numbers <- sort( which( cases[pz,] == 1 )-1 )
    ### first condition: same length
    if ( length(pz_numbers) == length(defect_numbers) ) {
      ### same condition: exacly same numbers
      if (all(pz_numbers == defect_numbers)) {
        ### append to found results vectors
        found_patients <- append( found_patients, cases[pz,1] )
        found_combos <- append( found_combos, i )
      }
    }
  }
}

output <- data.frame("CASE_ID" = found_patients,
                     "combo_no" = found_combos)

### result:
output
  CASE_ID combo_no
1    1002        2

ИЗМЕНЕНО на основании вашего комментария:

просто измените условия с равных на% в%:

### initialize vectors to store found results
found_combos <- vector(); found_patients <- vector();
for (i in 1:nrow(combos)) {
  ### open empty vector to fill with the numbers that compose the defect
  defect_numbers <- vector()
  ### open loop on column and take the numbers
  for (col in colnames(combos)[2:length(colnames(combos))]) {
    number <- combos[i, col]
    if ( !is.na(number) ) defect_numbers <- append(defect_numbers, number)
  }
  ### sort the vector to avoid mismatch based on order
  defect_numbers <- sort( defect_numbers )
  ### open loop on patients table
  for ( pz in 1:nrow(cases) ) {
    pz_numbers <- sort( which( cases[pz,] == 1 )-1 )
    ### only condition: all defect_numbers in combo_numbers vector
    if (all(defect_numbers %in% pz_numbers)) {
      ### append to found results vectors
      found_patients <- append( found_patients, cases[pz,1] )
      found_combos <- append( found_combos, i )
    }
  }
}

output <- data.frame("CASE_ID" = found_patients,
                     "combo_no" = found_combos)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...