dplyr slice: расставлять приоритеты на основе вектора, когда есть связь - PullRequest
0 голосов
/ 04 ноября 2018

Я пытаюсь выполнить следующую задачу с помощью dplyr.

У меня есть data.frame следующим образом

head(test_dat)

      PEAK MOTIF
    1   p1    m1
    2   p1    m2
    3   p1    m3
    4   p2    m1
    5   p2    m1
    6   p2    m2
    7   p3    m5
    8   p3    m3
    9   p3    m3

Я хотел бы присвоить уникальный MOTIF PEAK в зависимости от того, сколько раз он найден с этим конкретным значением PEAK.

test_dat %>% 
+   dplyr::group_by(PEAK) %>% 
+   dplyr::count(MOTIF) %>% 
+   dplyr::slice(which.max(n))

Это дает мне

  PEAK  MOTIF     n
  <fct> <fct> <int>
1 p1    m1        1
2 p2    m1        2
3 p3    m3        2

Что прекрасно, за исключением случаев, когда в столбце n указан галстук для PEAK, он выбрал первый. То есть в примере для p1, m1, m2, m3 найдены один раз, но в результате присваивается m1. Вместо этого я хотел бы присвоить MOTIF значение PEAK в соответствии с вектором, например,

motif_order = c("m2", "m1", "m3", "m5")

так что получается результат

  PEAK  MOTIF     n
  <fct> <fct> <int>
1 p1    m2        1
2 p2    m1        2
3 p3    m3        2

Я искал функции rank и slice, но я не нашел способа достичь этого в dplyr. Любые предложения / помощь будет принята с благодарностью.

Спасибо.

1 Ответ

0 голосов
/ 04 ноября 2018

Попробуйте:

library(dplyr)

df %>% mutate(MOTIF = factor(MOTIF, levels = c("m2", "m1", "m3", "m5"))) %>%
  add_count(PEAK, MOTIF) %>%
  group_by(PEAK) %>%
  arrange(n, MOTIF) %>%
  slice(which.max(n))

Выход:

  PEAK  MOTIF     n
  <chr> <fct> <int>
1 p1    m2        1
2 p2    m1        2
3 p3    m3        2

Вместо factor(MOTIF, levels = c("m2", "m1", "m3", "m5")) вы также можете ссылаться на motif_order, если он уже определен в среде, например, factor(MOTIF, levels = motif_order).

Если вам интересно, что-то подобное также будет работать в data.table:

library(data.table)

setDT(df)[, MOTIF := factor(MOTIF, levels = motif_order)][, .N, by = .(PEAK, MOTIF)][
  order(N, MOTIF), .SD[which.max(N)], by = PEAK]

Выход:

   PEAK MOTIF N
1:   p1    m2 1
2:   p2    m1 2
3:   p3    m3 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...