R 按行号和列号子集文件
我们希望在行和列上对文本文件进行子集,其中行和列的编号是从文件中读取的。不包括标题(第1行)和行名(第1列) inputFile.txt制表符分隔的文本文件R 按行号和列号子集文件,r,bash,awk,subset,bioinformatics,cut,R,Bash,Awk,Subset,Bioinformatics,Cut,我们希望在行和列上对文本文件进行子集,其中行和列的编号是从文件中读取的。不包括标题(第1行)和行名(第1列) inputFile.txt制表符分隔的文本文件 header 62 9 3 54 6 1 25 1 2 3 4 5 6 96 1 1 1 1 0 1 72 3 3 3 3 3 3 18 0 1 0 1 1 0 82 1 0 0 0 0 1 77 1 0
header 62 9 3 54 6 1
25 1 2 3 4 5 6
96 1 1 1 1 0 1
72 3 3 3 3 3 3
18 0 1 0 1 1 0
82 1 0 0 0 0 1
77 1 0 1 0 1 1
15 7 7 7 7 7 7
82 0 0 1 1 1 0
37 0 1 0 0 1 0
18 0 1 0 0 1 0
53 0 0 1 0 0 0
57 1 1 1 1 1 1
subsetCols.txt逗号分隔,不带空格,一行,数字按顺序排列。在实际数据中,我们有500K列,需要子集~10K
1,4,6
substrows.txt逗号分隔,不带空格,一行,数字按顺序排列。在实际数据中,我们有20K行,需要约300个子集
1,3,7
使用cut和awk循环()的当前解决方案:
输出文件:result.txt
1 4 6
3 3 3
7 7 7
问题:此解决方案适用于小文件,对于较大的文件(50K行和200K列),它需要花费太长的时间(15分钟以上),并且仍在运行。我认为cutting列工作得很好,选择行比较慢 还有更好的办法吗 真实输入文件信息:
# $fileInput:
# Rows = 20127
# Cols = 533633
# Size = 31 GB
# $fileCols: 12000 comma separated col numbers
# $fileRows: 300 comma separated row numbers
$ uname -a
Linux nYYY-XXXX ZZZ Tue Dec 18 17:22:54 CST 2012 x86_64 x86_64 x86_64 GNU/Linux
有关该文件的更多信息:该文件包含基因型数据。每行表示样本(单个),每列表示。对于进一步的基于区域的分析,我们需要对样本(行)和SNP(列)进行子集,以使数据更易于管理(小),作为其他统计软件(如)的输入
系统:
# $fileInput:
# Rows = 20127
# Cols = 533633
# Size = 31 GB
# $fileCols: 12000 comma separated col numbers
# $fileRows: 300 comma separated row numbers
$ uname -a
Linux nYYY-XXXX ZZZ Tue Dec 18 17:22:54 CST 2012 x86_64 x86_64 x86_64 GNU/Linux
更新:下面提供的解决方案是在我的系统中混合列的顺序,因为我使用的是不同版本的awk,我的版本是:
GNU awk 3.1.7
,尽管他们说
朝鲜。顽固地抵制变化,它的用户似乎出于我们只能推测的原因不自然地喜欢它
。。。无论何时,当你看到自己被塞德、切、格雷普、艾克等等,停下来对自己说:艾克可以独力完成
因此,在本例中,需要提取行和列(调整它们以排除标题和第一列),然后缓冲输出以最终打印它
awk -v cols="1 4 6" -v rows="1 3 7" '
BEGIN{
split(cols,c); for (i in c) col[c[i]] # extract cols to print
split(rows,r); for (i in r) row[r[i]] # extract rows to print
}
(NR-1 in row){
for (i=2;i<=NF;i++)
(i-1) in col && line=(line ? line OFS $i : $i); # pick columns
print line; line="" # print them
}' file
awk-v cols=“1 4 6”-v rows=“1 3 7”
开始{
拆分(cols,c);对于(c中的i)col[c[i]]#提取要打印的cols
拆分(行,r);对于(r中的i)行[r[i]]#提取要打印的行
}
(第1排为NR-1){
对于Gnu awk 4.0版或更高版本中的(i=2;i一个,因为列排序依赖于for
和PROCINFO[“sorted_in”]
。行号和列号从文件中读取:
$ awk '
BEGIN {
PROCINFO["sorted_in"]="@ind_num_asc";
}
FILENAME==ARGV[1] { # process rows file
n=split($0,t,",");
for(i=1;i<=n;i++) r[t[i]]
}
FILENAME==ARGV[2] { # process cols file
m=split($0,t,",");
for(i=1;i<=m;i++) c[t[i]]
}
FILENAME==ARGV[3] && ((FNR-1) in r) { # process data file
for(i in c)
printf "%s%s", $(i+1), (++j%m?OFS:ORS)
}' subsetRows.txt subsetCols.txt inputFile.txt
1 4 6
3 3 3
7 7 7
$awk'
开始{
PROCINFO[“排序在”]=“@ind\u num\u asc”;
}
FILENAME==ARGV[1]{#进程行文件
n=拆分($0,t,“,”);
为了(i=1;i不要从两个优秀答案中拿走任何东西。正因为这个问题涉及大量数据,我发布了两个答案的组合,以加快处理速度
awk -v cols="$(<subsetCols.txt)" -v rows="$(<subsetRows.txt)" '
BEGIN {
n = split(cols, c, /,/)
split(rows, r, /,/)
for (i in r)
row[r[i]]
}
(NR-1) in row {
for (i=1; i<=n; i++)
printf "%s%s", $(c[i]+1), (i<n?OFS:ORS)
}' inputFile.txt
awk-v cols=“$”(要优化@anubhava解决方案,我们可以
不要为每行搜索超过10k的值
利用输入已经排序的事实,看看我们是否在正确的一行
awk -v cols="$(<subsetCols.txt)" -v rows="$(<subsetRows.txt)" '
BEGIN {
n = split(cols, c, /,/)
split(rows, r, /,/)
j=1;
}
(NR-1) == r[j] {
j++
for (i=1; i<=n; i++)
printf "%s%s", $(c[i]+1), (i<n?OFS:ORS)
}' inputFile.txt
awk-v cols=“$”(Python有一个csv模块。您可以将一行读入列表,将所需的列打印到stdout、rinse、wash、repeat
这应该将列分割为20000到30000
import csv
with open('foo.txt') as f:
gwas = csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
for row in gwas:
print(row[20001:30001]
不太好。不过,如果你要测试它的话,我有点想听听它的性能。另外,我在几次会议上写了几篇文章,所以我很高兴听到它是否有效……QC之类的东西。:DNote,但是,使用for(c中的I)
可能无法提供正确的顺序:@JamesBrown好的一个!然后+1,做得好!这必须比我的解决方案快,因为它不会检查所有列是否必须打印;相反,它只是拾取它们。对了,James:不应该PROCINFO[“sorted_in”]=“@ind_num_asc”
是否在开始
块中设置?我很好奇,在读取第一个文件时设置它是否会影响其他文件。显然,该功能仅在更高版本中可用,4.0在某些地方提到过。哦,太酷了,您可以使用拆分的返回号来了解要检查的列数,从而在提取pr时使用它oper栏目号。这是非常聪明的,做得很好。我对awk了解不多,不能说这篇文章是否值得作为一个单独的答案,对我来说,它的变化似乎太小了,可能是对@anubhava的文章的评论?也许你应该在scale@Braiam那是个笑话…不知道为什么需要移除它。
import csv
with open('foo.txt') as f:
gwas = csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
for row in gwas:
print(row[20001:30001]