dplyr切片:存在平局时根据向量优先排序

时间:2018-11-04 09:46:09

标签: r dplyr

我正在尝试使用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

这很好,除了在列PEAK中有n的领带时,它选择了第一个。即在示例中,对于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

我正在搜索rankslice函数,但没有找到在dplyr中实现此目标的方法。任何建议/帮助将不胜感激。

谢谢。

1 个答案:

答案 0 :(得分:1)

尝试:

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