递归子集data.frame

时间:2016-05-18 21:29:26

标签: python r dataframe

我有一个数据框,其中有近400万行。我需要一种有效的方法来基于两个标准对数据进行子集化。我可以这样做是一个for循环,但想知道是否有更优雅的方式来做到这一点,显然更有效。 data.frame看起来像这样:

SNP         CHR     BP          P
rs1000000   chr1    126890980   0.000007
rs10000010  chr4    21618674    0.262098    
rs10000012  chr4    1357325     0.344192
rs10000013  chr4    37225069    0.726325    
rs10000017  chr4    84778125    0.204275    
rs10000023  chr4    95733906    0.701778
rs10000029  chr4    138685624   0.260899
rs1000002   chr3    183635768   0.779574
rs10000030  chr4    103374154   0.964166    
rs10000033  chr2    139599898   0.111846    
rs10000036  chr4    139219262   0.564791
rs10000037  chr4    38924330    0.392908    
rs10000038  chr4    189176035   0.971481    
rs1000003   chr3    98342907    0.000004
rs10000041  chr3    165621955   0.573376
rs10000042  chr3    5237152     0.834206    
rs10000056  chr4    189321617   0.268479
rs1000005   chr1    34433051    0.764046
rs10000062  chr4    5254744     0.238011    
rs10000064  chr4    127809621   0.000044
rs10000068  chr2    36924287    0.000003
rs10000075  chr4    179488911   0.100225    
rs10000076  chr4    183288360   0.962476
rs1000007   chr2    237752054   0.594928
rs10000081  chr1    17348363    0.517486    
rs10000082  chr1    167310192   0.261577    
rs10000088  chr1    182605350   0.649975
rs10000092  chr4    21895517    0.000005
rs10000100  chr4    19510493    0.296693    

我需要做的第一件事是选择SNP值低于阈值的P,然后按CHRPOS对此子集进行排序。这是一个简单的部分,使用subsetorder。但是,下一步是棘手的​​。一旦我有了这个子集,我需要从重要的SNP上下取出落入500,000窗口的所有SNP,此步骤将定义一个区域。我需要为所有重要的SNP执行此操作,并将每个区域存储到列表或类似的内容中以进行进一步分析。例如,在显示的数据框中,SNP的最重要CHR==chr1(即低于0.001的阈值)为rs1000000CHR==chr4rs10000092SNP。因此,这两个POS将定义两个区域,我需要在每个区域中获取SNP,这些SNP从每个最重要的SNP上下移动到500,000的区域{{1} }}。

我知道它有点复杂,现在,我正在手工制作棘手的部分,但这需要很长时间才能完成。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

以下是使用data.table的部分解决方案,这可能是处理大型数据集时R的最快方式。

library(data.table) # v1.9.7 (devel version)


df <- fread("C:/folderpath/data.csv") # load your data
setDT(df) # convert your dataset into data.table

第一步

# Filter data under threshold 0.05 and Sort by CHR, POS
  df <- df[ P < 0.05, ][order(CHR, POS)]

第二步

df[, {idx = (1:.N)[which.min(P)]
      SNP[seq(max(1, idx - 5e5), min(.N, idx + 5e5))]}, by = CHR]

将输出保存在不同的文件中

df[, fwrite(copy(.SD)[, SNP := SNP], paste0("output", SNP,".csv")), by = SNP]

PS。请注意,此答案使用的fwrite仍在data.table的开发版本中。 Go here for install instructions。你可以简单地使用write.csv,但是你要处理一个大数据集,所以速度非常重要,fwrite肯定是one of the fastest alternatives