1

我有一个包含 800000 行和 13000 列的文件。该文件如下所示:

        ID1 ID2 ID3 ID4 ID5
SNP1    AA  AA  AB  AA  BB
SNP2    AB  AA  BB  AA  AA
SNP3    BB  BB  BB  AB  BB
SNP4    AA  AA  BB  BB  AA
SNP5    AA  AA  AA  AA  AA

我想用数字替换字母(AA = 0,AB = 1 和 BB = 2)。我所做的是: data[data=="AA"] = 0 在一个小例子中它似乎工作正常,但在大文件中似乎没有完成这项工作。花了几个小时。有没有更有效的方法来做到这一点?非常感谢你。保拉。

4

3 回答 3

2

也许试试这个:

读入你的数据:

DF <- read.table(text = "ID1 ID2 ID3 ID4 ID5
SNP1    AA  AA  AB  AA  BB
SNP2    AB  AA  BB  AA  AA
SNP3    BB  BB  BB  AB  BB
SNP4    AA  AA  BB  BB  AA
SNP5    AA  AA  AA  AA  AA
", header = TRUE, sep = "", stringsAsFactors = FALSE) 

> str(DF)
'data.frame':   5 obs. of  5 variables:
 $ ID1: chr  "AA" "AB" "BB" "AA" ...
 $ ID2: chr  "AA" "AA" "BB" "AA" ...
 $ ID3: chr  "AB" "BB" "BB" "BB" ...
 $ ID4: chr  "AA" "AA" "AB" "BB" ...
 $ ID5: chr  "BB" "AA" "BB" "AA" ...

创建查找表:

tab <- c("AA" = 0, "AB" = 1  , "BB" = 2)
> tab
AA AB BB 
 0  1  2

一些子赋值魔法:

> DF[] <- tab[as.matrix(DF)]
> DF
     ID1 ID2 ID3 ID4 ID5
SNP1   0   0   1   0   2
SNP2   1   0   2   0   0
SNP3   2   2   2   1   2
SNP4   0   0   2   2   0
SNP5   0   0   0   0   0
> str(DF)
'data.frame':   5 obs. of  5 variables:
 $ ID1: num  0 1 2 0 0
 $ ID2: num  0 0 2 0 0
 $ ID3: num  1 2 2 2 0
 $ ID4: num  0 0 1 2 0
 $ ID5: num  2 0 2 0 0
于 2015-04-08T02:54:01.687 回答
2

文件对于 R 来说可能太大了,除非你使用scan,这会使 IMO 的事情变得过于复杂。使用 GNU 实用程序可以更好地处理这项工作。

如果您在 Windows 中安装 MSYS:

http://www.mingw.org/wiki/Getting_Started

然后sed如上所述使用替换文本:

cat <filename>  | sed "s/\bAA\b/0/g" | sed "s/\bBA\b/1/g" | sed "s/\bAB\b/1/g"  | sed "s/\bBB\b/2/g" > <newfile>

编辑:

如果您必须使用 R,您可能需要逐行读取文件,因为文件包含约 100 亿个条目,其中 3 个字符中的每一个确实是一个非常大的数据集!

请参阅此处的 SO 线程以逐行读取文件:

逐行读取R中的文本文件

但是,我怀疑这会很慢。

于 2015-04-08T13:34:36.700 回答
1

假设您已设法打开文件并假设它是data.frame带有factor列的,您可以使用因子已经是编号为的数字列的事实1

DF <- read.table(text = "ID1 ID2 ID3 ID4 ID5
SNP1    AA  AA  AB  AA  BB
SNP2    AB  AA  BB  AA  AA
SNP3    BB  BB  BB  AB  BB
SNP4    AA  AB  BB  BB  AA
SNP5    AA  AA  AA  AA  AA
", header = TRUE, sep = "") 

for (i in seq_along(DF)) {
  # check if the column levels are ordered correctly; if not
  # relevel the column
  if (!identical(levels(DF[[i]]), c("AA", "AB", "BB"))) {
    warning("Levels do not match in column ", i, ". Relevelling.")
    DF[[i]] <- factor(DF[[i]], levels=c("AA", "AB", "BB"))
  }
  # remove the class of the column: this basically makes an integer
  # column from the factor
  attr(DF[[i]], "class") <- NULL
  # substract 1 to get number from 0
  DF[[i]] <- DF[[i]] - 1
}

代码检查级别是否正确编号,并在必要时重新调整级别。希望这不会经常发生,因为这会减慢速度。

可能是您的文件不适合内存,这将导致 Windows/Linux/... 使用磁盘进行内存存储。这将大大减慢速度。在这种情况下,您可能最好使用ff或之类的包bigmemory

于 2015-04-08T14:51:27.687 回答