繁体   English   中英

用于根据跨列模式对行进行分组的 R 函数?

[英]R function for grouping rows based on patterns across columns?

我想根据每列跨列的模式对数据框的行进行分组。 这是一个非常简单的例子。

 df <- data.frame("gene" = 1:5, 
                 "stg 1" = c("up", "up", NA, NA, NA),
                 "stg 2" = c("up", "up", NA, NA, NA),
                 "stg 3" = c("up", "up", NA, NA, NA),
                 "stg 4" = c("down", "down", "up", "up", NA))

> df
  gene stg.1 stg.2 stg.3 stg.4
1    1    up    up    up  down
2    2    up    up    up  down
3    3  <NA>  <NA>  <NA>    up
4    4  <NA>  <NA>  <NA>    up
5    5  <NA>  <NA>  <NA>  <NA>

在这种情况下,基因 1 和 2 将被分组,基因 3 和 4 将被分组。 我想要每个模式组中基因的名称,以及该组的模式是什么。 我希望这很清楚。 提前致谢!

试试这个方法。 创建一个变量以使用c_across()toString() c_across()收集值。 之后,格式化为因子并分配后缀Group. . 这里使用tidyverse函数的代码:

library(tidyverse)
#Code
dfnew <- df %>% group_by(gene) %>% 
  mutate(Var=toString(c_across(stg.1:stg.4))) %>%
  ungroup() %>%
  mutate(Var=paste0('Group.',as.numeric(factor(Var,levels = unique(Var),ordered = T))))

输出:

# A tibble: 5 x 6
   gene stg.1 stg.2 stg.3 stg.4 Var    
  <int> <fct> <fct> <fct> <fct> <chr>  
1     1 up    up    up    down  Group.1
2     2 up    up    up    down  Group.1
3     3 NA    NA    NA    up    Group.2
4     4 NA    NA    NA    up    Group.2
5     5 NA    NA    NA    NA    Group.3

如果你只需要一个模式,试试这个:

#Code 2
dfnew <- df %>% group_by(gene) %>% 
  mutate(Var=toString(c_across(stg.1:stg.4)))

输出:

# A tibble: 5 x 6
# Groups:   gene [5]
   gene stg.1 stg.2 stg.3 stg.4 Var             
  <int> <fct> <fct> <fct> <fct> <chr>           
1     1 up    up    up    down  up, up, up, down
2     2 up    up    up    down  up, up, up, down
3     3 NA    NA    NA    up    NA, NA, NA, up  
4     4 NA    NA    NA    up    NA, NA, NA, up  
5     5 NA    NA    NA    NA    NA, NA, NA, NA 

我们可以通过unite以矢量化的方式做到这一点

library(dplyr)
library(tidyr)
df %>% 
     unite(grp, starts_with('stg'), na.rm = TRUE, remove = FALSE) %>% 
     mutate(grp = match(grp, unique(grp)))
#  gene grp stg.1 stg.2 stg.3 stg.4
#1    1   1    up    up    up  down
#2    2   1    up    up    up  down
#3    3   2  <NA>  <NA>  <NA>    up
#4    4   2  <NA>  <NA>  <NA>    up
#5    5   3  <NA>  <NA>  <NA>  <NA>

虽然没有特别要求,但data.table解决方案如下


library(data.table)
setDT(df)
df[,group:= paste0(stg.1,stg.2,stg.3,stg.4),by= gene][,group:= match(group, unique(group))]

> df
   gene stg.1 stg.2 stg.3 stg.4 group
1:    1    up    up    up  down     1
2:    2    up    up    up  down     1
3:    3  <NA>  <NA>  <NA>    up     2
4:    4  <NA>  <NA>  <NA>    up     2
5:    5  <NA>  <NA>  <NA>  <NA>     3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM