Использование grep для поиска частичных совпадений - PullRequest
0 голосов
/ 15 января 2020

Я хочу поместить подкадр данных в список переменных, и они должны присутствовать в нескольких столбцах

DO_concatenated

    LINHAA LINHAB  LINHAC LINHAD  LINHAII
1   *R58X   NA      NA      NA     NA
2   *P285   *P220   *P000   NA     NA
3   *A419   *N390   *I694   NA     NA
4   *G80X   NA      NA      NA     NA
5   *I64X   *I10X   *E119   *D649  NA
6   *R688   *J189   *C920   NA     NA
7   *A419   *J159   *C349   *J440  *E149
8   *A419   *J159   *C73X   *I10X  NA
9   *P269   *E872   *P369   NA     *P000
10  *P369   *P285   *Q870   NA     NA

Эти числа представляют некоторые коды ICD10, и я хочу отфильтровывать только коды редких заболеваний, которые содержатся во фрейме данных с именем "rare_diseases". Структура выглядит следующим образом:

   CID.10       rare.disease
1   D820    Sindrome de Wiskott-Aldrich
2   D821    Sindrome de Di George
3   E778    Sindrome de glicoproteinas deficientes em carboidratos
4   F70     Retardo mental leve
5   F71     Retardo mental moderado
6   F72     Retardo mental grave

Итак, я создал список с первым столбцом второго фрейма данных (cid10) и попытался создать grep:

a = DO_concatenated[(grep(cid10, DO_concatenated$LINHAA) | grep(cid10, DO_concatenated$LINHAB) |
                 grep(cid10, DO_concatenated$LINHAC) | grep(cid10, DO_concatenated$LINHAD) |
                   grep(cid10, DO_concatenated$LINHAII)),]

Но он возвращает фрейм данных с 0 переменными

Что я делаю не так и как я могу сделать частичное совпадение, так как первый df имеет "*" перед каждым кодом?

1 Ответ

1 голос
/ 15 января 2020

В вашем примере нет совпадений, поэтому его использование приведет к нулю строк. Я немного изменил примеры, чтобы проиллюстрировать, как разместить данные на основе условия, которое применяется к нескольким столбцам.

Во-первых, вот данные, с которыми мы будем работать:

DO_concatenated <- read.table(text = "    LINHAA LINHAB  LINHAC LINHAD  LINHAII
1   *F70   NA      NA      NA     NA
2   *P285   *P220   *P000   NA     NA
3   *A419   *N390   *I694   NA     NA
4   *G80X   NA      NA      NA     NA
5   *I64X   *D820   *E119   *D649  NA
6   *R688   *J189   *C920   NA     NA
7   *A419   *J159   *C349   *J440  *F70
8   *D820   *J159   *C73X   *D820  NA
9   *P269   *F70   *P369   NA     *P000
10  *P369   *E778   *Q870   NA     NA", stringsAsFactors = F)
DO_concatenated
#>    LINHAA LINHAB LINHAC LINHAD LINHAII
#> 1    *F70   <NA>   <NA>   <NA>    <NA>
#> 2   *P285  *P220  *P000   <NA>    <NA>
#> 3   *A419  *N390  *I694   <NA>    <NA>
#> 4   *G80X   <NA>   <NA>   <NA>    <NA>
#> 5   *I64X  *D820  *E119  *D649    <NA>
#> 6   *R688  *J189  *C920   <NA>    <NA>
#> 7   *A419  *J159  *C349  *J440    *F70
#> 8   *D820  *J159  *C73X  *D820    <NA>
#> 9   *P269   *F70  *P369   <NA>   *P000
#> 10  *P369  *E778  *Q870   <NA>    <NA>

rare_diseases <- read.table(text = "   CID.10       rare.disease
1   D820    'Sindrome de Wiskott-Aldrich'
2   D821    'Sindrome de Di George'
3   E778    'Sindrome de glicoproteinas deficientes em carboidratos'
4   F70     'Retardo mental leve'
5   F71     'Retardo mental moderado'
6   F72     'Retardo mental grave'", stringsAsFactors = F)
rare_diseases
#>   CID.10                                           rare.disease
#> 1   D820                            Sindrome de Wiskott-Aldrich
#> 2   D821                                  Sindrome de Di George
#> 3   E778 Sindrome de glicoproteinas deficientes em carboidratos
#> 4    F70                                    Retardo mental leve
#> 5    F71                                Retardo mental moderado
#> 6    F72                                   Retardo mental grave

Теперь, когда у нас есть данные, мы сначала преобразуем имена строк в новый столбец, затем мы go из от широкого к длинному формату, используя pivot_longer из tidyr, затем мы применяем фильтр на основе CID.10 в кадре данных rare_diseases. Наконец, мы pivot_wider вернемся к широкому формату. Этот метод сохранит только строку и код для редкого заболевания.

library(tidyverse)

DO_concatenated %>%
  rownames_to_column("row") %>%
  pivot_longer(cols = starts_with("LINH"), names_to = "col", values_to = "codes") %>%
  filter(grepl(paste(rare_diseases$CID.10, collapse = "|"), codes))  %>%
  pivot_wider(id_cols = "row", names_from = "col", values_from = codes)
#> # A tibble: 6 x 5
#>   row   LINHAA LINHAB LINHAII LINHAD
#>   <chr> <chr>  <chr>  <chr>   <chr> 
#>   1     *F70   <NA>   <NA>    <NA>  
#>   5     <NA>   *D820  <NA>    <NA>  
#>   7     <NA>   <NA>   *F70    <NA>  
#>   8     *D820  <NA>   <NA>    *D820 
#>   9     <NA>   *F70   <NA>    <NA>  
#>   10    <NA>   *E778  <NA>    <NA>

Другой вариант, если вы хотите сохранить все подряд, содержащее редкое заболевание, - использовать filter_at для фильтрации любой строки. где по крайней мере один столбец имеет редкое заболевание. Или мы можем свернуть все столбцы в один столбец, использовать grepl для фильтрации, а затем заново разделить столбцы.

DO_concatenated %>%
  filter_at(vars(starts_with("LINH")), 
            any_vars(grepl(paste(rare_diseases$CID.10, collapse = "|"), .)))
#>   LINHAA LINHAB LINHAC LINHAD LINHAII
#> 1   *F70   <NA>   <NA>   <NA>    <NA>
#> 2  *I64X  *D820  *E119  *D649    <NA>
#> 3  *A419  *J159  *C349  *J440    *F70
#> 4  *D820  *J159  *C73X  *D820    <NA>
#> 5  *P269   *F70  *P369   <NA>   *P000
#> 6  *P369  *E778  *Q870   <NA>    <NA>

DO_concatenated %>%
  unite(col = "new", sep = "_") %>%
  filter(grepl(paste(rare_diseases$CID.10, collapse = "|"), new)) %>%
  separate(new, into = colnames(DO_concatenated), sep = "_")
#>   LINHAA LINHAB LINHAC LINHAD LINHAII
#> 1   *F70     NA     NA     NA      NA
#> 2  *I64X  *D820  *E119  *D649      NA
#> 3  *A419  *J159  *C349  *J440    *F70
#> 4  *D820  *J159  *C73X  *D820      NA
#> 5  *P269   *F70  *P369     NA   *P000
#> 6  *P369  *E778  *Q870     NA      NA

И если вам нужно решение в base R

do.call(rbind, 
        lapply(colnames(DO_concatenated), function(x){
          DO_concatenated[grepl(paste(rare_diseases$CID.10, collapse = "|"),
                                DO_concatenated[,which(colnames(DO_concatenated) == x)]),]
          })
        )
#>    LINHAA LINHAB LINHAC LINHAD LINHAII
#> 1    *F70   <NA>   <NA>   <NA>    <NA>
#> 8   *D820  *J159  *C73X  *D820    <NA>
#> 5   *I64X  *D820  *E119  *D649    <NA>
#> 9   *P269   *F70  *P369   <NA>   *P000
#> 10  *P369  *E778  *Q870   <NA>    <NA>
#> 81  *D820  *J159  *C73X  *D820    <NA>
#> 7   *A419  *J159  *C349  *J440    *F70
...