首页 > 解决方案 > 如何通过改变值来选择每组的行?

问题描述

我有一个如下所示的数据集:

Group   Gene    Score   direct_count    secondary_count SD_per_group
  1    AQP11    0.31          4                5           0.12
  1    CLNS1A   0.27          0                2           0.12
  1    RSF1     0.49          3                6           0.12
  2    CFDP1    0.58          1                2           0.02
  2    CHST6    0.59          1                3           0.02
  2    UBL      0.56          1                3           0.02
  3    ACE      0.634         1                1           0.001
  3    NOS2     0.6345        1                1           0.001
  4    Gene1    0.1           10              20           0.45
  4    Gene2    0.68          3                1           0.45
  4    Gene3    0.7           0                1           0.45
  5    AGT      0.75          0                0           0.00

Score我根据它们与它们的关系选择每组某些基因,如果在每个过滤SD_per_group步骤中选择了超过 1 个基因。direct_countsecondary_count

我试图在第一个过滤步骤中为每组选择一个基因,如果与SD_per_group组中的其他人相比,最高得分 > 得分(然后如果选择了多个基因,我会根据count列选择基因,每组只保留几个基因如果他们也有匹配的直接和次要计数列)。

我对此进行了编码:

new_df <- df %>% 
  group_by(Group) %>% 
  filter((max(Score) - Score)<SD_per_group) %>% 
  slice_max(direct_count, n = 1) %>% 
  slice_max(secondary_count, n = 1) %>% 
  ungroup()

但是,如果组开始时只有 1 个基因,并且 SD_per_group 为 0.00,则不会为该组选择单个基因,但我需要它。

我如何使用filter((max(Score) - Score)<SD_Per_Group)占开始时只有 1 个基因的组?在我的示例数据中,我的代码没有为第 5 组选择任何内容。

输入数据:

structure(list(Group = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 4L, 
4L, 4L, 5L), Gene = c("AQP11", "CLNS1A", "RSF1", "CFDP1", "CHST6", 
"UBL", "ACE", "NOS2", "Gene1", "Gene2", "Gene3", "AGT"), Score = c(0.31, 
0.27, 0.49, 0.58, 0.59, 0.56, 0.634, 0.6345, 0.1, 0.68, 0.7, 
0.75), direct_count = c(4L, 0L, 3L, 1L, 1L, 1L, 1L, 1L, 10L, 
3L, 0L, 0L), secondary_count = c(5L, 2L, 6L, 2L, 3L, 3L, 1L, 
1L, 20L, 1L, 1L, 0L), SD_per_group = c(0.12, 0.12, 0.12, 0.02, 
0.02, 0.02, 0.001, 0.001, 0.45, 0.45, 0.45, 0)), row.names = c(NA, 
-12L), class = c("data.table", "data.frame"))

预期输出:

    
  Group Gene Score     direct_count secondary_count     SD_per_group
    1   RSF1    0.4900      3             6                0.120     #highest score >SD_per_group
    2   CHST6   0.5900      1             3                0.020     #highest secondary count
    3   ACE     0.6340      1             1                0.001     #ACE and NOS2 <SD diff and matching both counts
    3   NOS2    0.6345      1             1                0.001
    4   Gene2   0.6800      3             1                0.450    #highest direct count
    5   AGT     0.75        0             0                0.00     #only gene in the group so must be selected

标签: rdplyr

解决方案


如果我正确理解了您需要的逻辑,您想保留该组只有 1 行的任何行吗?

如果是这样,您可以or在过滤器中添加一条语句,以保留任何只有数量为 1 (ie n() == 1) 的行,如下所示:

代码

new_df <- df %>% 
  group_by(Group) %>% 
  filter((max(Score) - Score)<SD_per_group | n() == 1) %>% 
  slice_max(direct_count, n = 1) %>% 
  slice_max(secondary_count, n = 1) %>% 
  ungroup()

输出

> new_df
# A tibble: 6 x 6
  Group Gene  Score direct_count secondary_count SD_per_group
  <int> <chr> <dbl>        <int>           <int>        <dbl>
1     1 RSF1  0.49             3               6        0.12 
2     2 CHST6 0.59             1               3        0.02 
3     3 ACE   0.634            1               1        0.001
4     3 NOS2  0.634            1               1        0.001
5     4 Gene2 0.68             3               1        0.45 
6     5 AGT   0.75             0               0        0

推荐阅读