如何根据r中数值变量的间隔将数据帧拆分为子组

时间:2014-12-08 15:12:17

标签: r

我有一个数据框(df),如下所示:

mi       chr    gen.pos
m4774   Ch01    0
m4775   Ch01    1.701
m4663   Ch01    5.519
m4777   Ch01    6.5
m4779   Ch01    11.067
m4780   Ch01    11.234
m3933   Ch01    11.449
m4782   Ch01    13.986
m5534   Ch01    119.277
m5536   Ch02    0.036
m5550   Ch02    4.26

chr列作为群组,首先,通过此代码获取每个群组gen.pos列的20个区间的间隔:

len <- as.data.frame(cbind(chr = unique(df$chr), 
  do.call(rbind, tapply(df$gen.pos, df$chr, function(x) {c(min = min(x), max = max(x))}))))
len$interval <- format(round((as.numeric(as.character(len$max))-as.numeric(as.character(len$min)))/20,3),nsmall=3)

所以len数据框是:

chr     min     max     interval
Ch01    0       119.277 5.964
Ch02    0.036   134.249 6.711
Ch03    0.07    93.596  4.676
Ch04    0.392   134.342 6.698
Ch05    0.581   96.842  4.813
Ch06    0.008   131.802 6.59

我的任务是在bin中创建一个名为df的列,为每个组gen.pos的每个时间间隔分配索引#。例如,第一个分类1被分配到0~5.964范围gen.pos2分配给5.965 ~ 11.9285.964*2=11.928)... 最终结果如下:

mi      chr   gen.pos   bin
m4774   Ch01    0       1
m4775   Ch01    1.701   1
m4663   Ch01    5.519   1
m4777   Ch01    6.5     2
m4779   Ch01    11.067  2
m4780   Ch01    11.234  2
m3933   Ch01    11.449  2
m4782   Ch01    13.986  3
m5534   Ch01    119.277 20
m5536   Ch02    0.036   1
m5550   Ch02    4.26    1

不需要len数据帧输出。它只是用来更清楚地描述我的问题。感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

len是重要的光标,所以为了清楚起见,我在这里重现了

library(dplyr)
len <- df %>% 
         group_by(chr) %>%
         summarize(min=min(gen.pos), max=max(gen.pos), interval= (max-min)/20) 

假设bin宽度为b=interval,那么如果x=gen.pos与区间的端点不一致,则它会落入ceiling((x-min)/b)区间。所以

df %>% 
  group_by(chr) %>% 
  mutate(max   = max(gen.pos), 
         min   = min(gen.pos), 
         width = (max-min)/20, 
         bin1  = ceiling((gen.pos-min)/width),
         bin   = ifelse(gen.pos==min, bin1 + 1, bin1)
         ) 

将生成具有令人敬畏的dplyr的所需列。 (您可以使用select命令抛弃过时的列)