我正在尝试用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
中找不到实现这一点的方法。如有任何建议/帮助,我们将不胜感激。
谢谢。
尝试:
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
如果您已经在环境中定义了motif_order
,则也可以引用factor(MOTIF, levels = c("m2", "m1", "m3", "m5"))
,例如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