Сопоставьте несколько строк в нескольких столбцах и создайте один столбец да / нет (1/0) - PullRequest
0 голосов
/ 19 сентября 2018

Отредактировано, чтобы добавить код:

Я пытаюсь воспроизвести некоторые работы от коллеги, который использует SAS.У нас возникла проблема с импортом в SAS, который преобразует текст (который соответствует логическому) в числовой.

Цель этой работы - определить конкретные записи для передачи, поэтому нам нужно сохранить значения как импортированные изначально (что, я думаю, R сможет сделать).Прямо сейчас мы решаем проблему вручную, потому что это небольшое количество записей, но это не всегда может быть правдой.

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

Мне нужно иметь возможность оценить, есть ли одна из 34 потенциальных строк (иличастичные строки (в SAS двоеточие сокращает значение сравнения до той же длины, что и значение оценки и сравнивает их) в одном из 12 столбцов (например, Q16 означает, что строка должна начинаться только с Q16). Кроме того, любой из 12может иметь значение через него, становится более разреженным в более поздних полях.

Я пытаюсь найти наиболее эффективный и компактный подход, если это возможно.

Я все еще несколько новичок в R для болеесложные проблемы, поэтому я зашел в тупик. Я пробовал несколько подходов с grep и grepl, но ни один из них не принес никаких плодов. Когда я пробовал регулярное выражение, я пытался использовать каждую строкуиндивидуально в ifelse, а затем я также попробовал одну большую строку с оператором "|", но тоже не повезло.Я также попробовал базовый (применить) и dplyr подходы.

Любая помощь приветствуется.

Структура данных: Пример таблицы

Код для данных примера:

structure(list(record = 1:20, 
icd1 = c("Q753", "Q620", "Q825", "Q211", "Q828", "Q6532", "Q673", "Q380", "Q5310", "Q040", "Q107", "Q6689", "Q860", "Q753", "Q000", "Q673", "Q860", "Q673", "H9190", "Q381"), 
icd2 = c("Q141",NA,NA, "Q170", NA, NA, NA, NA, NA, NA, NA, "Q211", NA, NA, "Q211", "Q673", NA, "115", "Q759", "Q753"), 
icd3 = c("Q579", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q038", "H4657", "Q211"), 
icd4 = c("Q656", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q999", NA, NA), 
icd5 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q5301", NA, NA), 
icd6 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "Q168", NA, NA), 
icd7 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd8 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd9 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd10 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd11 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
icd12 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), 
.Names = c("record", "icd1", "icd2", "icd3", "icd4", "icd5", "icd6", "icd7", "icd8", "icd9", "icd10", "icd11", "icd12"), 
class = "data.frame", row.names = c(NA, -20L))

Интересующие строки:

case2 <- "^H4703| ^H90*| ^H91*| ^Q000| ^Q001| ^Q002| ^Q01*| ^Q02| ^Q03*|
^Q04*| ^Q05*| ^Q070*| ^Q110| ^Q111| ^Q112| ^Q120| ^Q122| ^Q130| ^Q138|
^Q139| ^Q141| ^Q142| ^Q143| ^Q148| ^Q149| ^Q16*| ^Q65*| ^Q66*| ^Q674| 
^Q688| ^Q743| ^Q758| ^Q759| ^Q828" 

Ответы [ 3 ]

0 голосов
/ 20 сентября 2018

Этот подход аналогичен @AndS, использующему pmatch для получения частичных совпадений.

1) Определение строк поиска в векторе:

case2 <- c("H4703", "H90", "H91", "Q000", "Q001", "Q002", "Q01", "Q02", "Q03",
"Q04", "Q05", "Q070", "Q110", "Q111", "Q112", "Q120", "Q122", "Q130", "Q138",
"Q139", "Q141", "Q142", "Q143", "Q148", "Q149", "Q16", "Q65", "Q66", "Q674", 
"Q688", "Q743", "Q758", "Q759", "Q828")

2) Делайте данные длинными и используйтеpmatch для идентификации и маркировки частичных совпадений.

library(tidyverse)
my_data2 <- my_data %>%
  gather(question, value, -record) %>%
  mutate(first_match = case2[pmatch(value, case2, duplicates.ok = TRUE)])

> head(my_data2)
  record question value first_match
1      1     icd1  Q753        <NA>
2      2     icd1  Q620        <NA>
3      3     icd1  Q825        <NA>
4      4     icd1  Q211        <NA>
5      5     icd1  Q828        Q828
6      6     icd1 Q6532        <NA>

3) Наконец, определите, какие строки имеют хотя бы одно совпадение:

my_data2 %>%
  group_by(record) %>%
  summarize(contains_string = any(!is.na(first_match)))

# A tibble: 20 x 2
   record contains_string
    <int> <lgl>          
 1      1 TRUE           
 2      2 FALSE          
 3      3 FALSE          
 4      4 FALSE          
 5      5 TRUE           
 6      6 FALSE          
 7      7 FALSE          
 8      8 FALSE          
 9      9 FALSE          
10     10 FALSE          
11     11 FALSE          
12     12 FALSE          
13     13 FALSE          
14     14 FALSE          
15     15 TRUE           
16     16 FALSE          
17     17 FALSE          
18     18 FALSE          
19     19 TRUE           
20     20 FALSE
0 голосов
/ 13 января 2019

Похоже, вы заново изобретаете сопутствующее назначение, для которого существует несколько пакетов R.Я создал icd около шести лет назад для этой цели, и он широко используется в сообществе.Это точно и очень быстро.Для вашего приложения я бы создал пользовательскую карту сопутствующей патологии (просто именованный список, каждый элемент которого был бы вектором соответствующих основ кода).

library(icd)
# x <- your_data_structure_above
examplemap <- list(
  case2 = c("H4703", "H90", "H91", "Q000", "Q001", "Q002", "Q01", "Q02", 
            "Q03", "Q04", "Q05", "Q070", "Q110", "Q111", "Q112", "Q120", 
            "Q122", "Q130", "Q138", "Q139", "Q141", "Q142", "Q143", "Q148", 
            "Q149", "Q16", "Q65", "Q66*", "Q674", "Q688", "Q743", "Q758", 
            "Q759", "Q828"))
icd::comorbid(x, examplemap)
0 голосов
/ 19 сентября 2018

Для этого я немного изменил вашу строку.Короче говоря, я преобразовал ваш фрейм данных из широкого в длинный, затем я суммировал каждый столбец как имеющий (ИСТИНА) или не имеющий (ЛОЖЬ) любую из строк, которые вы хотели.

case2 <- "H4703|H90|H91|Q000|Q001|Q002|Q01|Q02|Q03|Q04|Q05|Q070|Q110|Q111|Q112|Q120|Q122|Q130|Q138|Q139|Q141|Q142|Q143|Q148|Q149|Q16|Q65|Q66|Q674|Q688|Q743|Q758|Q759|Q828" 

library(dplyr)
library(tidyr)

df %>% 
  gather(column, string, -record) %>%
  group_by(column) %>%
  summarise(contains_string = sum(grepl(case2, string))>0) 
#> # A tibble: 12 x 2
#>    column contains_string
#>    <chr>  <lgl>          
#>  1 icd1   TRUE           
#>  2 icd10  FALSE          
#>  3 icd11  FALSE          
#>  4 icd12  FALSE          
#>  5 icd2   TRUE           
#>  6 icd3   TRUE           
#>  7 icd4   TRUE           
#>  8 icd5   FALSE          
#>  9 icd6   TRUE           
#> 10 icd7   FALSE          
#> 11 icd8   FALSE          
#> 12 icd9   FALSE

РЕДАКТИРОВАТЬ

Вот для каждой строки.

df %>% 
  gather(column, string, -record) %>%
  group_by(record) %>%
  mutate(contains_string = sum(grepl(case2, string))>0) %>%
  spread(column, string)
#> # A tibble: 20 x 14
#> # Groups:   record [20]
#>    record contains_string icd1  icd10 icd11 icd12 icd2  icd3  icd4  icd5 
#>     <int> <lgl>           <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#>  1      1 TRUE            Q753  <NA>  <NA>  <NA>  Q141  Q579  Q656  <NA> 
#>  2      2 FALSE           Q620  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  3      3 FALSE           Q825  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  4      4 FALSE           Q211  <NA>  <NA>  <NA>  Q170  <NA>  <NA>  <NA> 
#>  5      5 TRUE            Q828  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  6      6 TRUE            Q6532 <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  7      7 FALSE           Q673  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  8      8 FALSE           Q380  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#>  9      9 FALSE           Q5310 <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 10     10 TRUE            Q040  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 11     11 FALSE           Q107  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 12     12 TRUE            Q6689 <NA>  <NA>  <NA>  Q211  <NA>  <NA>  <NA> 
#> 13     13 FALSE           Q860  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 14     14 FALSE           Q753  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 15     15 TRUE            Q000  <NA>  <NA>  <NA>  Q211  <NA>  <NA>  <NA> 
#> 16     16 FALSE           Q673  <NA>  <NA>  <NA>  Q673  <NA>  <NA>  <NA> 
#> 17     17 FALSE           Q860  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
#> 18     18 TRUE            Q673  <NA>  <NA>  <NA>  115   Q038  Q999  Q5301
#> 19     19 TRUE            H9190 <NA>  <NA>  <NA>  Q759  H4657 <NA>  <NA> 
#> 20     20 FALSE           Q381  <NA>  <NA>  <NA>  Q753  Q211  <NA>  <NA> 
#> # ... with 4 more variables: icd6 <chr>, icd7 <chr>, icd8 <chr>,
#> #   icd9 <chr>

Создано в 2018-09-19 пакетом Представить (v0.2.0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...