【问题标题】:Select rows from df that make subgroups (one by one) based on their value从 df 中选择根据其值创建子组(一个接一个)的行
【发布时间】:2018-03-26 06:21:27
【问题描述】:

我的数据仍然存在障碍。这是可重现的df:

signal1 <- c(rep(1:6))
signal2 <- c(rep(7:12))
signal3 <- c(rep(13:18))
signal4 <- c(rep(19:24))
val <- c(2.5,3.2,2.9,0.1,0.4,4.1)
tag <- c('str1','str2','str3','str4','str5','str6')
gene <- c('ABC','ABC','ABC','DEF','DEF','DEF')
df <- data.frame(signal1,signal2,signal3,signal4,gene,FC)

  signal1 signal2 signal3 signal4 gene val
1       1       7      13      19  ABC 2.5
2       2       8      14      20  ABC 3.2
3       3       9      15      21  ABC 2.9
4       4      10      16      22  DEF 0.1
5       5      11      17      23  DEF 0.4
6       6      12      18      24  DEF 4.1

示例一

我想根据值val2.5 在组gene 中更大的值来选择产生连续、系列(2 个或更多)的行。问题是行应该是一一对应的,所以想要的输出应该是这样的:

  signal1 signal2 signal3 signal4 gene val
1       1       7      13      19  ABC 2.5
2       2       8      14      20  ABC 3.2
3       3       9      15      21  ABC 2.9

ABC 组中的三行满足条件 - 系列长度 - 3,一一对应,它们都有 val &gt;= 2.5

示例二

对于数据集:

  signal1 signal2 signal3 signal4 gene val
1       1       7      13      19  ABC 2.5
2       2       8      14      20  ABC 0.2
3       3       9      15      21  ABC 2.9
4       4      10      16      22  DEF 0.1
5       5      11      17      23  DEF 0.4
6       6      12      18      24  DEF 4.1

结果,空 df,因为组中的行都没有出现条纹。

示例三

  signal1 signal2 signal3 signal4 gene val
1       1       7      13      19  ABC 0.5
2       2       8      14      20  ABC 3.2
3       3       9      15      21  ABC 2.9
4       4      10      16      22  DEF 7.1
5       5      11      17      23  DEF 4.4
6       6      12      18      24  DEF 2.1

输出:

  signal1 signal2 signal3 signal4 gene val
2       2       8      14      20  ABC 3.2
3       3       9      15      21  ABC 2.9
4       4      10      16      22  DEF 7.1
5       5      11      17      23  DEF 4.4

两组/条纹/一系列行与val &gt;= 2.5一一对应

示例四

让我们来个更大的数据集:

   signal1 signal2 signal3 signal4 gene  val
1        1      11      21      31  ABC  0.5
2        2      12      22      32  ABC  3.2
3        3      13      23      33  ABC  2.9
4        4      14      24      34  ABC  7.1
5        5      15      25      35  ABC  0.4
6        6      16      26      36  DEF  4.1
7        7      17      27      37  DEF  6.2
8        8      18      28      38  DEF  0.2
9        9      19      29      39  DEF  3.2
10      10      20      30      40  DEF 12.1

一个输出:

   signal1 signal2 signal3 signal4 gene  val
2        2      12      22      32  ABC  3.2
3        3      13      23      33  ABC  2.9
4        4      14      24      34  ABC  7.1
6        6      16      26      36  DEF  4.1
7        7      17      27      37  DEF  6.2
9        9      19      29      39  DEF  3.2
10      10      20      30      40  DEF 12.1

我希望你看到我在寻找什么。

我试图用dplyr做点什么:

df %>%
  group_by(gene) %>%
  group_by(val >= 2.5)

示例 II 的数据结果:

# A tibble: 6 x 7
# Groups:   FC >= 2.5 [2]
  signal1 signal2 signal3 signal4 gene     FC `FC >= 2.5`
    <int>   <int>   <int>   <int> <fct> <dbl> <lgl>      
1       1       7      13      19 ABC   2.50  T          
2       2       8      14      20 ABC   2.40  F          
3       3       9      15      21 ABC   2.90  T          
4       4      10      16      22 DEF   0.100 F          
5       5      11      17      23 DEF   0.400 F          
6       6      12      18      24 DEF   4.10  T

现在至少在两次出现中一一选择我们有T 的行。在这种情况下,我们没有这种情况......

我将非常感谢您的帮助。

编辑:

akrun 提出的答案可以解决问题: 对于数据集:

   signal1 signal2 signal3 signal4 gene  val
1        1      11      21      31  ABC  0.5
2        2      12      22      32  ABC  3.2
3        3      13      23      33  ABC  0.9
4        4      14      24      34  ABC  7.1
5        5      15      25      35  ABC  0.4
6        6      16      26      36  DEF  4.1
7        7      17      27      37  DEF  6.2
8        8      18      28      38  DEF  0.2
9        9      19      29      39  DEF  0.2
10      10      20      30      40  DEF 12.1

我希望只有两行 DEF 编号为 6 和 7。

我们有:

# A tibble: 2 x 6
  signal1 signal2 signal3 signal4 gene    val
    <int>   <int>   <int>   <int> <fct> <dbl>
1       6      16      26      36 DEF    4.10
2       7      17      27      37 DEF    6.20

效果很好!

编辑 #2:

不幸的是我发现了一个小错误:

对于数据:

   signal1 signal2 signal3 signal4 gene  val
1        1      11      21      31  ABC  0.5
2        2      12      22      32  ABC  3.2
3        3      13      23      33  ABC  7.9
4        4      14      24      34  DEF  8.1
5        5      15      25      35  DEF  0.4
6        6      16      26      36  DEF  4.1
7        7      17      27      37  GHI  6.0
8        8      18      28      38  GHI  0.2
9        9      19      29      39  GHI  8.2
10      10      20      30      40  JKL 12.1

只应返回第 2 行和第 3 行及之后:

f1(df, gene, val)

我们有:

# A tibble: 6 x 6
  signal1 signal2 signal3 signal4 gene    val
    <int>   <int>   <int>   <int> <fct> <dbl>
1       2      12      22      32 ABC    3.20
2       3      13      23      33 ABC    7.90
3       4      14      24      34 DEF    8.10
4       6      16      26      36 DEF    4.10
5       7      17      27      37 GHI    6.00
6       9      19      29      39 GHI    8.20

但是您的第一个代码:

df %>% 
  group_by(gene, grp = rleid(val >= 2.5)) %>%
  filter(val >= 2.5, n() > 1) %>%
  ungroup %>%
  select(-grp)

返回:

# A tibble: 2 x 6
  signal1 signal2 signal3 signal4 gene    val
    <int>   <int>   <int>   <int> <fct> <dbl>
1       2      12      22      32 ABC    3.20
2       3      13      23      33 ABC    7.90

我认为 tidyverse 掩盖了 dplyr 功能,并且在 R 中重新启动会话后:

数据集:

signal1 <- c(rep(1:10))
signal2 <- c(rep(11:20))
signal3 <- c(rep(21:30))
signal4 <- c(rep(31:40))
val <- c(0.5,3.2,7.9,8.1,4.4,0.1,6.0,0.2,8.2,12.1)
tag <- c('str1','str2','str3','str4','str5','str6','str7','str8','str9','str10')
gene <- c('ABC','ABC','ABC','DEF','DEF','DEF','GHI','GHI','GHI','JKL')
df <- data.frame(signal1,signal2,signal3,signal4,gene,val)
df
   signal1 signal2 signal3 signal4 gene  val
1        1      11      21      31  ABC  0.5
2        2      12      22      32  ABC  3.2
3        3      13      23      33  ABC  7.9
4        4      14      24      34  DEF  8.1
5        5      15      25      35  DEF  4.4
6        6      16      26      36  DEF  0.1
7        7      17      27      37  GHI  6.0
8        8      18      28      38  GHI  0.2
9        9      19      29      39  GHI  8.2
10      10      20      30      40  JKL 12.1

通过以下方式获得的结果:

df %>% 
  group_by(gene, grp = rleid(val >= 2.5)) %>%
  filter(val >= 2.5, n() > 1) %>%
  ungroup %>%
  select(-grp

正确

# A tibble: 4 x 6
  signal1 signal2 signal3 signal4 gene    val
    <int>   <int>   <int>   <int> <fct> <dbl>
1       2      12      22      32 ABC    3.20
2       3      13      23      33 ABC    7.90
3       4      14      24      34 DEF    8.10
4       5      15      25      35 DEF    4.40

函数得到的结果:

f1 <- function(dat, grp1, grp2) {
  grp1 <- dplyr::enquo(grp1)
  grp2 <- dplyr::enquo(grp2)
  dat %>%
    dplyr::group_by(!! grp1) %>%
    dplyr::group_by(grp = data.table::rleid(!!(grp2) >= 2.5), add = TRUE) %>%
    dplyr::filter(val >= 2.5, n() > 1) %>%
    ungroup %>%
    dplyr::select(-grp)
}

# A tibble: 6 x 6
  signal1 signal2 signal3 signal4 gene    val
    <int>   <int>   <int>   <int> <fct> <dbl>
1       2      12      22      32 ABC    3.20
2       3      13      23      33 ABC    7.90
3       4      14      24      34 DEF    8.10
4       5      15      25      35 DEF    4.40
5       7      17      27      37 GHI    6.00
6       9      19      29      39 GHI    8.20

很遗憾,它不正确,GHI 中没有连续一行...

【问题讨论】:

  • 你能检查一下你的环境中加载的包吗?我认为可能还有其他具有filter 的软件包。一种选择是明确指定dplyr::filter
  • 可能是tidyverse,我做了编辑,dplyr ver 0.7.4
  • 你的rlang是什么版本
  • 亲爱的 Akrun,我重新安装了 dplyrdata.table,还删除了 tidyverse。我重新启动了R,终于finction工作了!你是R之神!我印象深刻
  • 我通常不会加载 tidyverse bcz 这个问题。很高兴知道该功能对您很有效。我是根据你们的问题来学习的。我没有什么特别的。

标签: r dataframe filter group-by dplyr


【解决方案1】:

基于示例,我们创建一个函数来执行filtering

library(data.table)
library(dplyr)

f1 <- function(dat, grp1, grp2) {
     grp1 <- enquo(grp1)
     grp2 <- enquo(grp2)
     dat %>%
        group_by(!! grp1) %>%
        group_by(grp = rleid(!!(grp2) >= 2.5), add = TRUE) %>%
        filter(val >= 2.5, n() > 1) %>%
        ungroup %>%
        select(-grp)
   }        

-示例一

f1(df1, gene, val)
# A tibble: 3 x 6
#  signal1 signal2 signal3 signal4 gene    val
#    <int>   <int>   <int>   <int> <chr> <dbl>
#1       1       7      13      19 ABC    2.50
#2       2       8      14      20 ABC    3.20
#3       3       9      15      21 ABC    2.90

-示例二

f1(df2, gene, val)
# A tibble: 0 x 6
# ... with 6 variables: signal1 <int>, signal2 <int>, signal3 <int>, signal4 <int>, gene <chr>, val <dbl>

-例子三

f1(df3, gene, val)
# A tibble: 4 x 6
#  signal1 signal2 signal3 signal4 gene    val
#    <int>   <int>   <int>   <int> <chr> <dbl>
#1       2       8      14      20 ABC    3.20
#2       3       9      15      21 ABC    2.90
#3       4      10      16      22 DEF    7.10
#4       5      11      17      23 DEF    4.40

-例子四

f1(df4, gene, val)
# A tibble: 7 x 6
# Groups: gene [2]
#  signal1 signal2 signal3 signal4 gene    val
#    <int>   <int>   <int>   <int> <chr> <dbl>
#1       2      12      22      32 ABC    3.20
#2       3      13      23      33 ABC    2.90
#3       4      14      24      34 ABC    7.10
#4       6      16      26      36 DEF    4.10
#5       7      17      27      37 DEF    6.20
#6       9      19      29      39 DEF    3.20
#7      10      20      30      40 DEF   12.1 

-示例V

f1(df5, gene, val)
# A tibble: 2 x 6
#  signal1 signal2 signal3 signal4 gene    val
#    <int>   <int>   <int>   <int> <chr> <dbl>
#1       6      16      26      36 DEF    4.10
#2       7      17      27      37 DEF    6.20

-示例六

f1(df6, gene, val)
# A tibble: 2 x 6
#  signal1 signal2 signal3 signal4 gene    val
#    <int>   <int>   <int>   <int> <chr> <dbl>
#1       2      12      22      32 ABC    3.20
#2       3      13      23      33 ABC    7.90

【讨论】:

  • 但是,当我们有多个组时,它会起作用吗?不仅有ABCDEF,还有更多GHIJKL 等?
  • @Adamm 我们按“基因”分组,所以“基因”中有多少级别并不重要
  • @Adamm 为了避免任何错误,我在按“基因”分组后创建了“grp”。
  • @Adamm 如果你运行 'f1' 的更新代码,你只会得到 2 行
  • @Adamm 你的 dplyr 版本是什么?我使用 0.7.4。你能在一个新的会话上运行吗
猜你喜欢
  • 2017-04-22
  • 1970-01-01
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
相关资源
最近更新 更多