Как создать фиктивную переменную для интервалов

Я хочу добавить столбец таблицы gwas, который указывает, какой ген он основан на начальной и конечной позиции гена. Как это сделать в dplyr?

> gwas
# A tibble: 1,220,764 x 13
   CHROM   POS ID             REF   ALT   A1    TEST  OBS_CT     BETA     SE  T_STAT      P ERRCODE
   <int> <int> <chr>          <chr> <chr> <chr> <chr>  <dbl>    <dbl>  <dbl>   <dbl>  <dbl> <chr>  
 1     1 10511 rs534229142    A     G     A     ADD   461822  0.0825  0.0439  1.88   0.0603 .      
 2     1 15031 rs568188357    A     G     A     ADD   461225  0.0410  0.0803  0.511  0.610  .      
 3     1 15245 rs576044687    T     C     T     ADD   461842  0.0369  0.0444  0.831  0.406  .      
 4     1 46285 1:46285_ATAT_A A     ATAT  A     ADD   461698  0.0205  0.0307  0.666  0.505  .      
 5     1 49315 rs567788405    A     T     A     ADD   460193  0.0576  0.0552  1.04   0.297  .      
 6     1 49318 rs536836601    G     A     G     ADD   460428  0.0297  0.0420  0.708  0.479  .      
 7     1 49343 rs553572247    C     T     C     ADD   461927 -0.00305 0.0360 -0.0846 0.933  .      
 8     1 51047 rs559500163    T     A     T     ADD   462466  0.0459  0.0402  1.14   0.254  .      
 9     1 51049 rs528344458    C     A     C     ADD   462466  0.0459  0.0402  1.14   0.254  .      
10     1 51050 rs551668143    T     A     T     ADD   462466  0.0459  0.0402  1.14   0.254  .      
# … with 1,220,754 more rows
> glist
# A tibble: 2,566 x 4
     chr     start       end gene_name
   <int>     <int>     <int> <chr>    
 1     1  33772366  33786699 A3GALT2  
 2     1  12776117  12788726 AADACL3  
 3     1  12704565  12727097 AADACL4  
 4     1  94458393  94586705 ABCA4    
 5     1 229652328 229694442 ABCB10   
 6     1  94883932  94984219 ABCD3    
 7     1 179068461 179198819 ABL2     
 8     1  76190031  76229363 ACADM    
 9     1   1227763   1243269 ACAP3    
10     1 226332379 226374423 ACBD3    
# … with 2,556 more rows

Я определил функцию

find_gene_name <- function(POS) {
  interval <- glist %>% filter(start<=POS, POS<=end)
  name <- interval$gene_name
  if(length(name)) {
    return(NA)
  } else {
    return(name) 
  }
}

Но получил ошибку при использовании по строкам.

> gwas_annotated <- gwas %>% 
+   rowwise() %>%
+   mutate(gene_name=find_gene_name(POS))
Error: Problem with `mutate()` input `gene_name`.
x Input `gene_name` can't be recycled to size 1.
ℹ Input `gene_name` is `find_gene_name(POS)`.
ℹ Input `gene_name` must be size 1, not 0.
ℹ Did you mean: `gene_name = list(find_gene_name(POS))` ?
ℹ The error occurred in row 1.
Run `rlang::last_error()` to see where the error occurred.

person monotonic    schedule 17.12.2020    source источник
comment
каков ожидаемый результат в этом случае?   -  person Onyambu    schedule 18.12.2020
comment
Просто дополнительный столбец gwas с именем gene_name, если POS находится в этом интервале   -  person monotonic    schedule 18.12.2020
comment
Самым быстрым способом было бы неэквивалентное соединение data.table. Вы также можете попробовать нечеткие соединения. См. Этот пример stackoverflow.com/ questions / 24480031 /   -  person Ronak Shah    schedule 18.12.2020
comment
Это кажется немного другим. @RonakShah   -  person monotonic    schedule 18.12.2020
comment
Для начала у меня нет идентификатора.   -  person monotonic    schedule 18.12.2020
comment
не столкнетесь ли вы также с проблемой, что может быть более одного интервала генов, в который попадает значение POS в таблице gwas?   -  person brian avery    schedule 18.12.2020
comment
Нет, интервалы не перекрываются @brianavery   -  person monotonic    schedule 18.12.2020
comment
одно из решений в этом вопросе должно работать для u. stackoverflow.com/questions/64725878/   -  person StupidWolf    schedule 19.12.2020
comment
в противном случае я бы сказал, что вам лучше предоставить хороший ввод и ожидаемый результат   -  person StupidWolf    schedule 19.12.2020


Ответы (1)


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

gwas <- data.frame(chr=rep(1,8), 
                   pos=c(10511,15031,15245,30123,46285,49315,49318,51047),
                   ID=LETTERS[1:8])
glist <- data.frame(chr=rep(1,9), 
                    start=c(12,10250,11237,15000,45500,49010,51001,67000,81000),
                    end=c(900,11113,12545,16208,47123,50097,51987,69000,83000),
                    name=c("kitty","tabby","scratch","spot","princess",
                           "buddy","tiger","rocky","peep"))
> gwas
  chr   pos ID
1   1 10511  A
2   1 15031  B
3   1 15245  C
4   1 30123  D
5   1 46285  E
6   1 49315  F
7   1 49318  G
8   1 51047  H
> glist
  chr start   end     name
1   1    12   900    kitty
2   1 10250 11113    tabby
3   1 11237 12545  scratch
4   1 15000 16208     spot
5   1 45500 47123 princess
6   1 49010 50097    buddy
7   1 51001 51987    tiger
8   1 67000 69000    rocky
9   1 81000 83000     peep

вот способ решить эту проблему, используя вложенные циклы for, которые ненавидят многие люди R:

res_names <- vector(mode="character")
for(i in 1:nrow(gwas)){
  for(j in 1:nrow(glist)){
    if(gwas$pos[i] <= glist$end[j] & gwas$pos[i] >= glist$start[j]){
      res_names[i] <- glist$name[j]
    }
  }
}
gwas$loop_gene <- res_names

вот версия вашей функции для поиска имени гена:

library(dplyr)
find_gene_name <- function(pos) {
  interval <- glist %>% filter(start<=pos, pos<=end)
  if(nrow(interval)<1){
    gname <- NA # or "none" etc. 
  } else {
    gname <- interval$name
  }
  return(gname)
}

затем его можно использовать в apply вызове:

gwas$apply_gene <- sapply(gwas$pos, find_gene_name)

или, как вы пытались использовать rowwise и mutate из dplyr:

gwas_annotated <- gwas %>% 
  rowwise() %>%
  mutate(dplyr_gene=find_gene_name(pos))
gwas_annotated

так, как я настроил это в скрипте, я получаю все 3 столбца имен генов с одинаковыми именами:

> gwas_annotated
# A tibble: 8 x 6
# Rowwise: 
    chr   pos ID    loop_gene apply_gene dplyr_gene
  <dbl> <dbl> <chr> <chr>     <chr>      <chr>     
1     1 10511 A     tabby     tabby      tabby     
2     1 15031 B     spot      spot       spot      
3     1 15245 C     spot      spot       spot      
4     1 30123 D     NA        NA         NA        
5     1 46285 E     princess  princess   princess  
6     1 49315 F     buddy     buddy      buddy     
7     1 49318 G     buddy     buddy      buddy     
8     1 51047 H     tiger     tiger      tiger   
person brian avery    schedule 21.12.2020