Как вернуть соответствующий столбец исходного фрейма данных после создания нового фрейма данных с помощью dplyr

#r

#r

Вопрос:

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

 head(BLAST)
     qseqid                 sseqid staxids  pident bitscore   evalue length mismatch qstart qend
1:  k127_70 ref|NZ_MCGG01000042.1|   28181  73.930    102.0 1.57e-20    257       65    228  483
2:  k127_84 ref|NZ_FXXN01000027.1| 1979370  80.690    110.0 5.76e-23    145       24     70  212
3:  k127_84       ref|NC_007626.1|  342108  78.621     93.5 5.80e-18    145       27     70  212
4:  k127_86     gb|PEAC01000057.1| 2032654 100.000     62.1 2.41e-08     33        0    408  440
5: k127_311 ref|NZ_LWQU01000152.1| 1437059  72.709    292.0 3.63e-77    993      227     30 1006
6: k127_311     ref|NZ_FO538765.1| 1288970  72.778    222.0 4.83e-56    720      172     20  727
   qcovhsp qcovs
1:      53    53
2:      47    47
3:      47    47
4:       8     8
5:      50    50
6:      36    36
                                                                                                              taxonomy
1:        Proteobacteria,Alphaproteobacteria,Rhodospirillales,Rhodospirillaceae,Magnetovibrio,Magnetovibrio blakemorei
2:    Proteobacteria,Alphaproteobacteria,Rhodospirillales,Rhodospirillaceae,Magnetospirillum,Magnetospirillum sp. 15-1
3:  Proteobacteria,Alphaproteobacteria,Rhodospirillales,Rhodospirillaceae,Magnetospirillum,Magnetospirillum magneticum
4:                                                                Nitrospirae,NA,NA,NA,NA,Nitrospirae bacterium MYbin6
5: Proteobacteria,Alphaproteobacteria,Rhodospirillales,Rhodospirillaceae,Magnetospirillum,Magnetospirillum moscoviense
6:            Proteobacteria,Alphaproteobacteria,Rhodospirillales,Rhodospirillaceae,Magnetospira,Magnetospira sp. QH-2
  

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

 Max.BLAST <- BLAST %>%
  group_by(taxonomy) %>%
  summarize(evalue = max(evalue),
            bitscore = max(bitscore),
            pident = max(pident))


head(Max.BLAST)
# A tibble: 6 x 4
  taxonomy                                                                     evalue bitscore pident
  <chr>                                                                         <dbl>    <dbl>  <dbl>
1 Candidatus Omnitrophica,NA,NA,NA,Candidatus Omnitrophus,Candidatus Omni…    1.00e-6     1118    100
2 Candidatus Omnitrophica,NA,NA,NA,NA,Candidatus Omnitrophica bacterium       1.00e-6      630    100
3 NA,NA,NA,NA,NA,bacterium FH-1                                               8.27e-7      169    100
4 NA,NA,NA,NA,NA,magneto-ovoid bacterium MO-1                                 9.95e-7     1474    100
5 Nitrospirae,NA,NA,NA,NA,Nitrospirae bacterium                               1.00e-6     1110    100
6 Nitrospirae,NA,NA,NA,NA,Nitrospirae bacterium MYbin3                        9.95e-7      893    100
  

Как мне получить соответствующий столбец «qseqid» для фрейма данных Max.BLAST?

Заранее благодарю.

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

1. Привет, я не знаю подробностей ваших данных, но, вероятно, то, что вы хотите, не совсем возможно: строка, для которой значение evalue является максимальным, может отличаться qseqid от строки, для которой bitscore значение maximal .

2. Уважаемый @ Cettt, значения должны совпадать друг с другом. 🙂

Ответ №1:

Попробуйте:

 Max.BLAST <- BLAST %>%
  group_by(taxonomy) %>%
  mutate(evalue = max(evalue),
            bitscore = max(bitscore),
            pident = max(pident))
  

Ответ №2:

вы можете попробовать это:

 Max.BLAST <- BLAST %>%
  group_by(taxonomy) %>%
  summarize(evalue = max(evalue),
            bitscore = max(bitscore),
            pident = max(pident)) %>%
    semi_join(BLAST, . , by = c("taxonomy", "evalue", "bitscore", "pident")) %>%
    select(qseqid, taxonomy, evalue, bitscore, pident) %>%
    distinct()
  

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

1. Уважаемый @ Cettt, к сожалению, у меня это не сработало. dim(Max.BLAST) [1] 47 4 A <- BLAST %>% group_by(таксономия) %>% summary(evalue = max(оценка), bitscore = max(bitscore), pident = max(pident)) %>% semi_join(BLAST, . , by = c(«таксономия», «оценка»)) %>% select(qseqid, taxonomy, evalue, bitscore, pident) dim(A) [1] 173 5 Мне нужны только 47 таксономий ичтобы получить их соответствующий qseqid. Спасибо, что просмотрели это.

2. Уважаемый @Cettt, к сожалению, это тоже не сработало. B <- BLAST %>% group_by(таксономия) %>% summary(evalue = max(оценка), bitscore = max(bitscore), pident = max(pident)) %>% semi_join(BLAST, . , by = c(«таксономия», «оценка», «bitscore», «pident»)) %>% select(qseqid, taxonomy, evalue, bitscore, pident) %>% distinct() dim(B) [1] 0 5

3. можете поделиться выводом dput(BLAST) внутри вашего вопроса (не в качестве комментария). Если ваши данные слишком велики, выберите соответствующее подмножество.

Ответ №3:

Ответ @Cetttt выше должен работать, но вот другое решение без объединения :

 Max.BLAST <- BLAST %>%
    group_by(taxonomy) %>%
    mutate(is_max = evalue == max(evalue)) %>%
    filter(is_max == TRUE) %>%
    ungroup()
  

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

 set.seed(10042019)
nrows <- 50

BLAST <- data.frame(
  id = paste0('id_', 1:nrows),
  taxonomy = sample(letters[1:5], size = nrows, replace = T),
  evalue = runif(nrows),
  bitscore = rnorm(nrows),
  stringsAsFactors = F
) 

head(BLAST)

BLAST %>%
  group_by(taxonomy) %>%
  filter(evalue == max(evalue)) %>%
  ungroup()
  

Если вы хотите быть уверенным, что он соответствует всем максимумам, вы можете использовать filter_at :

 BLAST <- mutate(BLAST, bitscore = evalue * 2.5)
BLAST %>%
  group_by(taxonomy) %>%
  filter_at(vars(evalue, bitscore), all_vars(. == max(.))) %>% 
  ungroup()
  

Обратите внимание, что это последнее решение может привести к получению пустого data.frame, если максимумы не достигнуты для одной и той же строки!