R按列中的数字对数据进行分组

问题描述

我正在尝试按列中的数字对数据进行分组,我尝试了不同版本的 group_by,剪切,分组等,但我无法获取我有很多看起来像这样的数据:

  position variants

     3      snv
     5      snv
    12      snv
    17      mnv
    22 deletion
    27      snv
    33      snv
    35      snv
    42      snv
    46      mnv
    50      snv
    53 deletion
    60      snv
    62      snv
    65      snv
    70      snv
variants <- c(rep("snv",3),rep("mnv",1),rep("deletion",rep("snv",4),"mnv",rep("snv"),"deletion",4))
variants              
position = c(3,5,12,17,22,27,33,35,42,46,50,53,60,62,65,70)
position
patient1 = data.frame(position,variants)
patient1

我希望能够对数据进行分组 像这样的东西:

group  tally
1-10    2snv
11-20   1snv 1mnv
21-30   1deletion 1snv
31-40   2snv 
etc

以便我可以进行进一步的下游分析。 并能够将其更改为 1-5或1-2等的组 非常感谢你

解决方法

这里是纯R解决方案。当然,您可以用相应的调用替换变量:

variants <- c(rep("snv",3),rep("mnv",1),rep("deletion",rep("snv",4),"mnv",rep("snv"),"deletion",4))
position = c(3,5,12,17,22,27,33,35,42,46,50,53,60,62,65,70)
patient1 = data.frame(position,variants)

labels = cut(position,seq(0,max(position),10))
groups = split(patient1,labels)
lapply(groups,function(x) {
  paste( table(x$variants),names(table(x$variants)),collapse = "," )
      }
  )
,

我们可以使用tidvyerse按操作分组。根据{{​​1}}和“变量”创建cutsummarise频率计数的一组范围,然后在cut中将它们paste一起{ >

summarise

注意:另一个选项是library(dplyr) patient1 %>% group_by(group = cut(position,breaks = c(-Inf,seq(1,100,by = 10))),variants) %>% summarise(n = n()) %>% summarise(tally = paste(n,variants,collapse=' ',sep="")) ,其功能与findInterval类似,但没有cut,因为它将输出数字索引

,

在基数R中,您可以使用findInterval创建一个组列,每10个位置进行分组。然后,我们可以使用aggregate并将variants的计数与variants结合起来,为每个组创建一个字符串。

patient1$group <- with(patient1,findInterval(position,(seq(0,10))))

aggregate(variants~group,patient1,function(x) {
  tb <- table(x)
  paste(tb,names(tb),collapse = ' ')
})

#  group         variants
#1     1            2 snv
#2     2      1 mnv 1 snv
#3     3 1 deletion 1 snv
#4     4            2 snv
#5     5      1 mnv 1 snv
#6     6 1 deletion 1 snv
#7     7            3 snv
#8     8            1 snv