R

[R|skills] 提取大文件的特定行列

2019-11-05  本文已影响0人  drlee_fc74

需求描述

我们在用R做数据分析的时候,需要把数据集导入到R里面。但是有时候由于文件太大,我们的内存又很小。这个时候就导入不进去。假如我们打开大的数据集只是想提取其中一部分数据该怎么做呢?

由于目标的自数据集,我们都知道一个唯一的ID,所以只需要基于唯一ID来进行提取就行

我这里是是有一个pancancer的数据集。想要提取其中几个基因的数据。

image.png

解决方法1

第一反应想到的是,那既然R解决不了。我可以在shell上写个循环。使用唯一id来进行提取数据。

cat id.txt | whlie read id; do (grep ${id} file); done > result

通过这个方式是可以进行检索,但是由于文件太大。shell当中的grep。应该是要遍历检索所有的数据和这个目标ID是否匹配。所以会相当的慢。

解决方法2

由于grep可能是遍历检索所有的数据来进行匹配,所以会很慢。而我们的数据集其实只需要在第一列上进行匹配即可。这个时候就想到,其实我们可以用R来分段加载数据,然后进行匹配。再把所有匹配的结果组合到一起。
在导入文件的参数当中,通过nrows可以指定我们想要加载多少行。通过skip可指定我们来跳过多少行。因此我们可以通过这两个参数构建一个循环来提取数据
在R的导入文件名的速度上而言,还是data.table::fread想到来说快一些。所以我们使用fread来进行匹配

具体操作

  1. 我们先导入我们想要查找的ID。
options(stringsAsFactors = F)
library(data.table)
targetid <- read.table("targetgene.txt")
targetid <- targetid$V1
head(targetid)
  1. 知道大文件有多少行。

这个如果用shell的话。wc -l一下即可。
但是既然用R。那就用R计算一下吧。在不打开全部文件的情况下。我们通过select参数加载第一列来查看有多少行

rownum <- nrow(fread("tcga_Kallisto_tpm", select = 1L, header = F))
rownum
  1. 构建循环提取目标序列。我们以15000为一个单位。每次加载15000行来提取数据
## 确定有多个个15000
index <- seq(0,rownum, by = 15000)
##构建循环
result <- c()
for(i in index){
    dat <- fread("tcga_Kallisto_tpm", nrows = 15000,skip = i, header = F, data.table = F)
    result1 <- dat[dat$V1 %in% targetid, ]
    result <- rbind(result, result1)
}

扩展:提取指定的列

上面说的是如果提取指定的行,但是如果想要提取指定的列的时候,例如,我想提取某些样本所有基因的表达。这个时候可以借助fread当中的select来指定目标列的位置就行

例如我的目标列是

targetcol <- sample(result[1,], 100)
targetcol <- as.data.frame(t(targetcol))
targetcol1 <- targetcol$`1`

1, 获取相对应的位置。

通过加载第一行进行匹配来获得相对应的位置

row1 <- fread("tcga_Kallisto_tpm", nrows = 1, header = F, data.table = F)
row2 <- as.data.frame(t(row1))
row2 <- row2$V1
index <- sapply(targetcol1, function(x) which(row2 == x))
  1. 构建循环加载数据
resultCol <- c()
for(i in index){
    resultCol1 <- fread("tcga_Kallisto_tpm", select = i)
    resultCol <- rbind(resultCol, resultCol1)
}
上一篇下一篇

猜你喜欢

热点阅读