Мутировать, если какой-либо столбец содержит список значений

#r #multiple-columns #data-wrangling

Вопрос:

Я работаю с кодами МКБ и нуждаюсь в вашей помощи, пытаясь изменить дополнительную колонку «нейро» на основе неврологических состояний, связанных с МКБ. Вот пример набора данных, с которым я работаю:

 ID `ICD9 1` `ICD9 2` `ICD9 3` `ICD9 4` `ICD9 5` `ICD9 6` `ICD9 7` `ICD9 8` `ICD9 9`  lt;chrgt; lt;chrgt; lt;chrgt; lt;chrgt; lt;chrgt; lt;chrgt; lt;chrgt; lt;chrgt; lt;chrgt; lt;chrgt;  1 20002038 927 NA NA NA NA NA NA NA NA  2 20003011 460 NA NA NA NA NA NA NA NA  3 20003019 320 V22 473 V22 V22 724 NA NA NA  4 20003026 719 490 729 724 NA NA NA NA NA  5 20004018 724 401 436 287 780 NA NA NA NA  6 20007016 523 339 NA NA NA NA NA NA NA   

Как бы я это сделал: (a) проверьте, содержат ли какие-либо столбцы ICD9 следующие коды ICD, представляющие интерес:

 ICD = c(320:337, 339:359 and 430:438)  

(b) затем добавьте дополнительный столбец «нейро» на основе строк, содержащих интересующий код ICD.

Я пробовал следующие решения, в которых много ошибок. Первый метод наиболее перспективен, но по какой-то причине возвращает «0» :

 for(i in 2:ncol(df)){  x = c(320:337, 339:359 and 430:438)  test lt;- test %gt;%   mutate(neuro = ifelse(i %in% x, 1, 0) ) }  

Я также попробовал это сделать с гораздо меньшим успехом:

 x = c(320:337, 339:359 and 430:438) df lt;- df %gt;%   mutate(neuro = ifelse(apply(df == x, 1, any), 1, 0))  

Я, вероятно, совершаю много-много ошибок, и мне было неприятно пытаться понять это в течение нескольких часов. Был бы признателен за вашу помощь — спасибо!

Ответ №1:

нам может понадобиться if_any

 library(dplyr) ICD lt;- c(320:337, 339:359, 430:438) df lt;- df %gt;%  mutate(neuro =  (if_any(starts_with("ICD"), ~. %in% ICD)))  

-выход

 df  ID ICD 1 ICD 2 ICD 3 ICD 4 ICD 5 ICD 6 ICD 7 ICD 8 ICD 9 neuro 1 20002038 927 lt;NAgt; NA lt;NAgt; lt;NAgt; NA NA NA NA 0 2 20003011 460 lt;NAgt; NA lt;NAgt; lt;NAgt; NA NA NA NA 0 3 20003019 320 V22 473 V22 V22 724 NA NA NA 1 4 20003026 719 490 729 724 lt;NAgt; NA NA NA NA 0 5 20004018 724 401 436 287 780 NA NA NA NA 1 6 20007016 523 339 NA lt;NAgt; lt;NAgt; NA NA NA NA 1  

Когда вектор length больше 1, == он не будет работать так, как элементарно, нам может понадобиться %in% , и это должно зацикливать across столбцы так, как %in% требуется вектор в качестве входных данных ( df == x или df %in% x не будет работать)

данные

 df lt;- structure(list(ID = c(20002038L, 20003011L, 20003019L, 20003026L,  20004018L, 20007016L), `ICD 1` = c(927L, 460L, 320L, 719L, 724L,  523L), `ICD 2` = c(NA, NA, "V22", "490", "401", "339"), `ICD 3` = c(NA,  NA, 473L, 729L, 436L, NA), `ICD 4` = c(NA, NA, "V22", "724",  "287", NA), `ICD 5` = c(NA, NA, "V22", NA, "780", NA), `ICD 6` = c(NA,  NA, 724L, NA, NA, NA), `ICD 7` = c(NA, NA, NA, NA, NA, NA), `ICD 8` = c(NA,  NA, NA, NA, NA, NA), `ICD 9` = c(NA, NA, NA, NA, NA, NA)),  class = "data.frame", row.names = c("1",  "2", "3", "4", "5", "6"))  

Комментарии:

1. Большое вам спасибо — я несколько ЧАСОВ боролся, пытаясь понять это!

Ответ №2:

Вот альтернативный подход. Лучше всего то, что с if_any помощью as предоставляется от akrun!

 library(tidyverse) df %gt;%   mutate(across(-ID, ~ifelse(. %in% ICD, 1,0), .names = 'new_{col}')) %gt;%   unite(New_Col, starts_with('new'), na.rm = TRUE, sep = ' ') %gt;%   mutate(neuro = str_extract(New_Col, "1"), .keep="unused") %gt;%  mutate(neuro = replace_na(neuro, 0))  
 ID ICD 1 ICD 2 ICD 3 ICD 4 ICD 5 ICD 6 ICD 7 ICD 8 ICD 9 neuro 1 20002038 927 lt;NAgt; NA lt;NAgt; lt;NAgt; NA NA NA NA 0 2 20003011 460 lt;NAgt; NA lt;NAgt; lt;NAgt; NA NA NA NA 0 3 20003019 320 V22 473 V22 V22 724 NA NA NA 1 4 20003026 719 490 729 724 lt;NAgt; NA NA NA NA 0 5 20004018 724 401 436 287 780 NA NA NA NA 1 6 20007016 523 339 NA lt;NAgt; lt;NAgt; NA NA NA NA 1  

Комментарии:

1. Большое вам спасибо!

Ответ №3:

Возможно, мы можем попробовать

 df$neuro lt;-  (rowSums(matrix(as.matrix(df[-1]) %in% ICD, nrow = nrow(df))) gt; 0)  

такой, что

 gt; df  ID ICD 1 ICD 2 ICD 3 ICD 4 ICD 5 ICD 6 ICD 7 ICD 8 ICD 9 neuro 1 20002038 927 lt;NAgt; NA lt;NAgt; lt;NAgt; NA NA NA NA 0 2 20003011 460 lt;NAgt; NA lt;NAgt; lt;NAgt; NA NA NA NA 0 3 20003019 320 V22 473 V22 V22 724 NA NA NA 1 4 20003026 719 490 729 724 lt;NAgt; NA NA NA NA 0 5 20004018 724 401 436 287 780 NA NA NA NA 1 6 20007016 523 339 NA lt;NAgt; lt;NAgt; NA NA NA NA 1  

Комментарии:

1. Большое вам спасибо! Это было так полезно 🙂