Arrays 从数组中调用特定元素

Arrays 从数组中调用特定元素,arrays,perl,bioinformatics,Arrays,Perl,Bioinformatics,好的,我有一堆文件名,具有以下两种格式之一: 样本-ID\U适配器-Sequence\U L001\U R1\U 001.fastq(正向) 样本-ID\U适配器-Sequence\U L001\U R2\U 001.fastq(与之相反) 正向和反向格式之间的唯一区别是文件名中的R1和R2元素。现在,我已使用以下脚本使用户能够提供包含这些文件的目录: #!/usr/bin/perl use strict; use warnings; #Print Directory print "Plea

好的,我有一堆文件名,具有以下两种格式之一:

样本-ID\U适配器-Sequence\U L001\U R1\U 001.fastq(正向)

样本-ID\U适配器-Sequence\U L001\U R2\U 001.fastq(与之相反)

正向和反向格式之间的唯一区别是文件名中的R1和R2元素。现在,我已使用以下脚本使用户能够提供包含这些文件的目录:

#!/usr/bin/perl
use strict;
use warnings;

#Print Directory

print "Please provide the directory containing the FASTQ files from your Illumina MiSeq run \n";
my $FASTQ = <STDIN>;
chomp ($FASTQ);

#Open Directory

my $dir = $FASTQ;
opendir(DIR, $dir) or die "Cannot open $dir: $!";
my @forwardreads = grep { /R1_001.fastq/ } readdir DIR;
closedir DIR;

my $direct = $FASTQ;
opendir(DIR, $direct) or die "Cannot open $dir: $!";
my @reversereads = grep { /R2_001.fastq/ } readdir DIR;
closedir DIR;

foreach my $ffile (@forwardreads) {
    my $forward = $ffile;
    print $forward;
    }

foreach my $rfile (@reversereads) {
    my $reverse = $rfile;
    print $reverse;
    }
#/usr/bin/perl
严格使用;
使用警告;
#打印目录
打印“请提供包含Illumina MiSeq运行中FASTQ文件的目录\n”;
我的$FASTQ=;
chomp($FASTQ);
#开放目录
my$dir=$FASTQ;
opendir(DIR,$DIR)或die“无法打开$DIR:$!”;
my@forwardreads=grep{/R1_001.fastq/}readdir;
closedir;
my$direct=$FASTQ;
opendir(DIR,$direct)或die“无法打开$DIR:$!”;
my@reversereads=grep{/R2_001.fastq/}readdir;
closedir;
foreach my$ffile(@forwardreads){
我的$forward=$ffile;
打印$forward;
}
每个我的$rfile(@reversereads){
my$reverse=$rfile;
打印$reverse;
}
问题 我想对上面的脚本做的是找到一种方法,将两个数组中从相同样本ID派生的元素配对。正如我所说的,正向和反向文件(来自相同样本ID)之间的唯一区别是文件名的R1和R2部分

我尝试过寻找从数组中提取元素的方法,但我想让程序代替我进行匹配


谢谢你们的阅读,希望你们能帮忙

您必须解析出文件名。幸运的是,这非常简单。剥离扩展后,您可以在
\uu
上删除碎片

# Strip the file extension.
my($suffix) = $filename =~ s{\.(.*?)$}{};

# Parse Sample-ID_Adapter-Sequence_L001_R1_001
my($sample_id, $adapter_sequence, $uhh, $format, $yeah) = split /_/, $filename;
现在你可以用它们做你喜欢的事了

我想提出一些改进代码的建议。首先,将文件名解析放入一个函数中,这样就可以重用它,并使主代码更简单。第二,将文件名解析为一个散列,而不是一堆标量,这样更易于使用和传递。最后,将文件名本身包含在该散列中,然后该散列包含完整的数据。顺便说一句,这是面向对象编程的门户

sub parse_fastq_filename {
    # Read the next (in this case first and only) argument.
    my $filename = shift;

    # Strip the suffix
    my($suffix) = $filename =~ s{\.(.*?)$}{};

    # Parse Sample-ID_Adapter-Sequence_L001_R1_001
    my($sample_id, $adapter_sequence, $uhh, $format, $yeah) = split /_/, $filename;

    return {
        filename            => $filename,
        sample_id           => $sample_id,
        adapter_sequence    => $adapter_sequence,
        uhh                 => $uhh,
        format              => $format,
        yeah                => $yeah
    };
}
然后,不要单独查找左右格式化文件,而是在一个循环中处理所有内容。将匹配的左、右对放入散列。使用
glob
仅拾取
.fastq
文件

# This is where the pairs of files will be stored.
my %pairs;

# List just the *.fastq files
while( my $filename = glob("$FASTQ_DIR/*.fastq")) {
    # Parse the filename into a hash reference
    my $fastq = parse_fastq_filename($filename);

    # Put each parsed fastq filename into its pair
    $pairs{ $fastq->{sample_id} }{ $fastq->{format} } = $fastq;
}
然后,您可以使用
%对
执行您喜欢的操作。下面是一个打印每个示例ID及其格式的示例

# Iterate through each sample and pair.
# $sample is a hash ref of format pairs
for my $sample (values %pairs) {
    # Now iterate through each pair in the sample
    for my $fastq (values %$sample) {
        say "$fastq->{sample_id} has format $fastq->{format}";
    }
}

你能以纯文本的形式提供你的代码吗?只需将其剪切并粘贴到您的帖子中,突出显示它,然后单击
{}
“代码示例”按钮。如果你不能得到正确的格式,有人会修复它。谢谢!代码已经准备好了!如果您只想找到这些对,那么不需要在perl脚本中进行。只需通过管道将输出传输到两个额外的unix命令,如下所示(假设文件名的R1/2部分前面有3个下划线):
your_script.pl | cut-d'-f 1,2,3 | sort | uniq-c | sort-n
。你们所有的一对将在底部。如果你想的话,你也可以把它们涂成灰色,去掉前导空格/数字。您也可以在perl中执行类似的操作。虽然效率不高,但它很简单,而且几乎总是足够。这与您的问题无关,但我建议使用
glob
,而不是
readdir
grep
。e、 g.
my@forwardreads=glob('*R1_001.fastq”);
我在删除脚本中的“foreach”组件后放置了建议的代码。我收到错误“使用未初始化值$filename替换(s//”)“在子例程中。此错误也适用于拆分。我应该在代码中保留foreach元素吗?另外,我还有下面的unix命令,我希望在其中分别调用该对的两个元素。按照您的建议设置后,我可以调用这对中的每个元素吗?@Postan92您在
$filename
中输入了什么?听起来你从来没有给它分配过任何东西。至于你能用
%对
做什么,快发疯吧!在子例程中,我将我的
$filename
调用为
shift@reads
。在子例程之外,接近脚本末尾时,我复制了您的建议和对。@Postan92我不知道
@reads
是什么,里面可能什么都没有。子例程中没有我的$filename=shift@reads
,是吗?这将使子程序从一个特定的全局变量中读取时变得不那么有用。相反,您应该为我的$filename(@reads){my$fastq=parse_fastq_filename($filename);…}
,将文件名传递到例程中,并保留
my$filename=shift在例程中。很抱歉,我的速度很慢,但是如果我在子例程中调用
my$filename=shift
,它不会调用任何数组,因为我调用的数组超出了子例程的范围(我在脚本开始时要求用户输入包含所有感兴趣文件的目录)。这是我剧本唯一的问题。