按列绑定几个大矩阵
Binding several large matrices by column
我真的知道 'large matrix issue' 是这里反复出现的话题,但我想详细解释一下我关于大矩阵的具体问题。
严格来说,我想 cbind
几个在 R 中具有特定名称模式的大矩阵。下面的代码展示了我迄今为止的最佳尝试。
首先让我们生成文件来模拟我的真实矩阵:
# The df1
df1 <- '######## infx infx infx
######## infx infx infx
probeset_id sample1 sample2 sample3
PR01 1 2 0
PR02 -1 2 0
PR03 2 1 1
PR04 1 2 1
PR05 2 0 1'
df1 <- read.table(text=df1, header=T, skip=2)
write.table(df1, "df1.txt", col.names=T, row.names=F, quote=F, sep="\t")
# The df2
df2 <- '######## infx infx infx
######## infx infx infx
probeset_id sample4 sample5 sample6
PR01 2 2 1
PR02 2 -1 0
PR03 2 1 1
PR04 1 2 1
PR05 0 0 1'
df2 <- read.table(text=df2, header=T, skip=2)
write.table(df2, "df2.txt", col.names=T, row.names=F, quote=F, sep="\t")
# The dfn
dfn <- '######## infx infx infx
######## infx infx infx
probeset_id samplen1 samplen2 samplen3
PR01 2 -1 1
PR02 1 -1 0
PR03 2 1 1
PR04 1 2 -1
PR05 0 2 1'
dfn <- read.table(text=dfn, header=T, skip=2)
write.table(dfn, "dfn.txt", col.names=T, row.names=F, quote=F, sep="\t")
然后将其导入到 R 并按照我的预期写入 output
文件:
### Importing and excluding duplicated 'probeset_id' column
calls = list.files(pattern="*.txt")
library(data.table)
calls = lapply(calls, fread, header=T)
mycalls <- as.data.frame(calls)
probenc <- as.data.frame(mycalls[,1])
mycalls <- mycalls[, -grep("probe", colnames(mycalls))]
output <- cbind(probenc, mycalls)
names(output)[1] <- "probeset_id"
write.table(output, "output.txt", col.names=T, row.names=F, quote=F, sep="\t")
输出的样子:
> head(output)
probeset_id sample1 sample2 sample3 sample4 sample5 sample6 samplen1 samplen2 samplen3
1 PR01 1 2 0 2 2 1 2 -1 1
2 PR02 -1 2 0 2 -1 0 1 -1 0
3 PR03 2 1 1 2 1 1 2 1 1
4 PR04 1 2 1 1 2 1 1 2 -1
5 PR05 2 0 1 0 0 1 0 2 1
此代码非常适合我想做的事情,但是,我使用真实数据时遇到了已知的 R 内存限制(超过 30 个“df
”对象,约 1.3GB or/and 60 万行,每行 100 列)。
我读到过一个非常有趣的 SQL 方法 (R: how to rbind two huge data-frames without running out of memory),但我对 SQL 缺乏经验,并且没有找到适合我的情况的方法。
干杯,
我之前误解了这个问题;现在评论说得很清楚了。然后你需要的是使用像 ff
这样的包。这使您可以使用硬盘中的文件,而不是将它们加载到 RAM 中。这看起来像是您的问题的解决方案,因为您提到 RAM 不足以加载系统中的所有文件。
首先使用 read.table.ffdf
加载文件,然后使用以下命令将它们绑定在一起:
#load files in R
library(ff)
df1 <- read.table.ffdf('df1.txt', header=T, skip=2)
df2 <- read.table.ffdf('df2.txt', header=T, skip=2)
dfn <- read.table.ffdf('dfn.txt', header=T, skip=2)
然后像这样合并:
mergedf <- do.call('ffdf', c(physical(df1), physical(df2), physical(dfn)))
不幸的是,我无法使用您的示例,因为 read.table.ffdf
不支持文本参数,但上面的方法应该有效。 ff
包有自己的(不是很复杂的)语法,您可能需要熟悉它,因为它可以处理硬盘上的文件。例如 apply
函数是使用 ffapply
函数完成的,其方式与 apply
.
几乎相同
查看 here, here and here 包 ff
的一些基本教程。
您还可以查看包内的函数并使用内置帮助来帮助自己 ls(package:ff)
。
我真的知道 'large matrix issue' 是这里反复出现的话题,但我想详细解释一下我关于大矩阵的具体问题。
严格来说,我想 cbind
几个在 R 中具有特定名称模式的大矩阵。下面的代码展示了我迄今为止的最佳尝试。
首先让我们生成文件来模拟我的真实矩阵:
# The df1
df1 <- '######## infx infx infx
######## infx infx infx
probeset_id sample1 sample2 sample3
PR01 1 2 0
PR02 -1 2 0
PR03 2 1 1
PR04 1 2 1
PR05 2 0 1'
df1 <- read.table(text=df1, header=T, skip=2)
write.table(df1, "df1.txt", col.names=T, row.names=F, quote=F, sep="\t")
# The df2
df2 <- '######## infx infx infx
######## infx infx infx
probeset_id sample4 sample5 sample6
PR01 2 2 1
PR02 2 -1 0
PR03 2 1 1
PR04 1 2 1
PR05 0 0 1'
df2 <- read.table(text=df2, header=T, skip=2)
write.table(df2, "df2.txt", col.names=T, row.names=F, quote=F, sep="\t")
# The dfn
dfn <- '######## infx infx infx
######## infx infx infx
probeset_id samplen1 samplen2 samplen3
PR01 2 -1 1
PR02 1 -1 0
PR03 2 1 1
PR04 1 2 -1
PR05 0 2 1'
dfn <- read.table(text=dfn, header=T, skip=2)
write.table(dfn, "dfn.txt", col.names=T, row.names=F, quote=F, sep="\t")
然后将其导入到 R 并按照我的预期写入 output
文件:
### Importing and excluding duplicated 'probeset_id' column
calls = list.files(pattern="*.txt")
library(data.table)
calls = lapply(calls, fread, header=T)
mycalls <- as.data.frame(calls)
probenc <- as.data.frame(mycalls[,1])
mycalls <- mycalls[, -grep("probe", colnames(mycalls))]
output <- cbind(probenc, mycalls)
names(output)[1] <- "probeset_id"
write.table(output, "output.txt", col.names=T, row.names=F, quote=F, sep="\t")
输出的样子:
> head(output)
probeset_id sample1 sample2 sample3 sample4 sample5 sample6 samplen1 samplen2 samplen3
1 PR01 1 2 0 2 2 1 2 -1 1
2 PR02 -1 2 0 2 -1 0 1 -1 0
3 PR03 2 1 1 2 1 1 2 1 1
4 PR04 1 2 1 1 2 1 1 2 -1
5 PR05 2 0 1 0 0 1 0 2 1
此代码非常适合我想做的事情,但是,我使用真实数据时遇到了已知的 R 内存限制(超过 30 个“df
”对象,约 1.3GB or/and 60 万行,每行 100 列)。
我读到过一个非常有趣的 SQL 方法 (R: how to rbind two huge data-frames without running out of memory),但我对 SQL 缺乏经验,并且没有找到适合我的情况的方法。
干杯,
我之前误解了这个问题;现在评论说得很清楚了。然后你需要的是使用像 ff
这样的包。这使您可以使用硬盘中的文件,而不是将它们加载到 RAM 中。这看起来像是您的问题的解决方案,因为您提到 RAM 不足以加载系统中的所有文件。
首先使用 read.table.ffdf
加载文件,然后使用以下命令将它们绑定在一起:
#load files in R
library(ff)
df1 <- read.table.ffdf('df1.txt', header=T, skip=2)
df2 <- read.table.ffdf('df2.txt', header=T, skip=2)
dfn <- read.table.ffdf('dfn.txt', header=T, skip=2)
然后像这样合并:
mergedf <- do.call('ffdf', c(physical(df1), physical(df2), physical(dfn)))
不幸的是,我无法使用您的示例,因为 read.table.ffdf
不支持文本参数,但上面的方法应该有效。 ff
包有自己的(不是很复杂的)语法,您可能需要熟悉它,因为它可以处理硬盘上的文件。例如 apply
函数是使用 ffapply
函数完成的,其方式与 apply
.
查看 here, here and here 包 ff
的一些基本教程。
您还可以查看包内的函数并使用内置帮助来帮助自己 ls(package:ff)
。