我有一个包含p值的文件,如果在每行的至少一列中看到p值< = 0.05,并且不删除该行,我希望过滤它。 / p>
该文件的简化版本看起来像(但实际上有30,000行和327列):
gene,speciesA,speciesB,speciesC
X,0.05,0.9, 2.6426944282e-05
Y,1,0.6,0.006
Z,1,1,1
因此,如果基因X在至少一个物种中具有显着价值,那么保留该基因。如果它没有删除该基因。
我编写了一个perl脚本,但我不知道如何让它以比编写每一列更合乎逻辑的方式在所有行中预先形成过滤器。
use strict;
use warnings;
open my $file, '<', $ARGV[0] or die "$!";
my ($line);
$line = (<$file>);
print $line; #keep the header
while ( $line = <$file> ) {
chomp $line;
my @ranges = split( ",", $line );
print join( "\t", @ranges ), "\n"
if ( $ranges[1] <= 0.05 ); #need to filter for 327 columns and ignore column[0]
答案 0 :(得分:2)
使用perl one-liner:
perl -F, -lane 'print if $. == 1 || ! grep {$_ <= 0.05} @F[1..$#F]' file.csv
切换:
-F
:split()
模式-a
切换-l
:启用行结束处理-a
:拆分空间线并将其加载到数组@F
-n
:为输入文件中的每个“行”创建一个while(<>){...}
循环。 -e
:告诉perl
在命令行上执行代码。 <强>代码强>:
$. == 1
:检查当前行是否为第1行。! grep {$_ <= 0.05} @F[1..$#F]
:确保没有值等于或低于0.05 答案 1 :(得分:1)
这将按照你的要求行事。
请注意,我正在阅读DATA
文件句柄以进行测试。如果要从具有硬编码名称的文件中读取,请写入
open my $fh, '<', 'myfile' or die $!;
而不是my $fh = \*DATA
。或者,您想要从命令行中命名的文件中读取,然后将<$fh>
替换为<>
。
use strict;
use warnings;
use List::Util 'any';
my $fh = \*DATA;
print scalar <$fh>; # Copy header
while (<$fh>) {
chomp;
my @fields = split /,/;
shift @fields;
print "$_\n" if any { $_ <= 0.05 } @fields;
}
__DATA__
gene,speciesA,speciesB,speciesC
X,0.05,0.9,2.6426944282e-05
Y,1,0.6,0.006
Z,1,1,1
<强>输出强>
gene,speciesA,speciesB,speciesC
X,0.05,0.9,2.6426944282e-05
Y,1,0.6,0.006
答案 2 :(得分:0)
看起来你有一个CSV文件。另一种选择可能是使用DBD::CSV driver的DBI:
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect ("dbi:CSV:", undef, undef, {
f_ext => "./csv",
RaiseError => 1,
}) or die "Cannot connect: $DBI::errstr";
# Selecting
my $sth = $dbh->prepare ("select * from foo where the_column_name<0.05");
$sth->execute;
while( my $hr = $sth->fetchrow_hashref ) {
#...
}