【问题标题】:Parse MEDLINE file for GWAS mining解析 MEDLINE 文件以进行 GWAS 挖掘
【发布时间】:2014-09-06 09:34:04
【问题描述】:

我正在尝试将 MedLine 文件解析为 0,1 表以执行一些统计下游分析:PCA、GWAS 等。我使用名为 Bio.Medline 的 Python 模块和一些额外的 shell 命令对其进行了格式化。现在,我不知道如何继续。

我需要将 File 1, - 每行一张纸和制表符分隔的关键字的键值文件 - 转换为包含折叠关键字和关键字的存在/不存在显示为 1 或 0 值的文件。

我想用 Perl 来做这件事,但欢迎使用其他解决方案。

谢谢,伯纳多

File 1:

19801464    Animals Biodiversity    Computational Biology/methods   DNA
19696045    Environmental Microbiology  Computational Biology/methods   Software

期望的输出:

    Animals Biodiversity    Computational Biology/methods   DNA Environmental Microbiology  Software
19801464    1   1   1   0   0
19696045    0   1   0   1   1

【问题讨论】:

  • 第一次通过的方法是遍历所有关键字并将它们放入一个数组中。现在,通过文档的行和每个 paperID,在哈希对象(Ruby 中的papers["19801464"])中创建一个新对象,并根据关键字的存在为该哈希分配每个关键字的键和值 0 或 1在那一行(Ruby 中的papers["19801464"]["Animal Biodiversity"] = 1)。
  • 不应该在您想要的输出中记录19696045 在“环境微生物学”的第 4 列中有一个“1”?
  • 是的 G. Cito,我更新了它。
  • 我转到 PCA 步骤,这里是:stats.stackexchange.com/questions/108148/…

标签: python perl parsing bioinformatics bioperl


【解决方案1】:

您可以使用 Python 和 Pandas 执行此操作:

In [1]: df = pd.read_table("file", header=None, sep="\t", names=["A", "B","C","D"], index_col=0)
In [2]: df
Out[2]: 
          A                           B                              C  \
0  19801464        Animals Biodiversity  Computational Biology/methods   
1  19696045  Environmental Microbiology  Computational Biology/methods   

          D  
0       DNA  
1  Software  

In [3]: b = pd.get_dummies(df.B)

In [4]: c = pd.get_dummies(df.C)

In [5]: d = pd.get_dummies(df.D)

In [6]: presence_absence = b.merge(c, right_index=True, left_index=True).merge(d,right_index=True, left_index=True)

In [7]: presence_absence
Out[7]: 
          Animals Biodiversity  Environmental Microbiology  \
A                                                            
19801464                     1                           0   
19696045                     0                           1   

          Computational Biology/methods  DNA  Software  
A                                                       
19801464                              1    1         0  
19696045                              1    0         1

希望对你有帮助

【讨论】:

    【解决方案2】:

    这个perl 脚本将构建一个您应该能够使用的哈希。为方便起见,我使用List::MoreUtils 表示uniqData::Printer 转储数据结构:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use List::MoreUtils qw(uniq);
    use DDP;
    
    my %paper ;
    my @categories;
    
    while (<DATA>){
      chomp;
      my @record = split /\t/ ;
      $paper{$record[0]}  = { map { $_ => 1 } @record[1..$#record] } ;
      push @categories , @record[1..$#record] ;
    }
    
    @categories = uniq @categories; 
    
    foreach (keys %paper) {
      foreach my $category(@categories) {
        $paper{$_}{$category} //= 0 ;
      } 
    }; 
    
    p %paper ;
    
    __DATA__
    19801464   Animals Biodiversity  Computational Biology/methods  DNA     
    19696045   Environmental Microbiology   Computational Biology/methods Software
    

    输出

    {
        19696045   {
            'Animals Biodiversity'            0,
            'Computational Biology/methods'   1,
            DNA                               0,
            'Environmental Microbiology'      1,
            Software                          1
        },
        19801464   {
            'Animals Biodiversity'            1,
            'Computational Biology/methods'   1,
            DNA                               1,
            'Environmental Microbiology'      0,
            Software                          0
        }
    }
    

    从那里到产生你想要的输出可能需要printf 来正确格式化这些行。以下内容可能足以满足您的目的:

    print "\t", (join "  ", @categories); 
    for (keys %paper) {
      print "\n", $_, "\t\t" ;
      for my $category(@categories) { 
        print $paper{$_}{$category}," "x17 ; 
      }  
    }
    

    编辑

    格式化输出的一些替代方案...(我们使用x 将格式部分乘以@categories 数组中的长度或元素数量,以便它们匹配):

    使用format

    my $format_line = 'format STDOUT =' ."\n"
                    . '@# 'x ~~@categories . "\n" 
                    . 'values %{ $paper{$num} }' . "\n"
                    . '.'."\n"; 
    for $num (keys %paper) {
      print $num ;
      no warnings 'redefine'; 
      eval $format_line;
    write;
    }
    

    使用printf

    print (" "x9, join "  ", @categories, "\n"); 
    for $num (keys %paper) {
      print $num  ;
      map{ printf "%19d", $_ }  values %{ $paper{$num} } ;
      print "\n";   
    }
    

    使用form

    use Perl6::Form;                                                              
    for $num (keys %paper) {                                                       
      print form                                                         
      "{<<<<<<<<}" . "{>}" x ~~@categories ,                                      
        $num       , values %{ $paper{$num} }                                      
    }
    

    根据您计划对数据执行的操作,您可能可以在 perl 中完成其余的分析,因此在工作流程的后期阶段,打印的精确格式可能不是优先事项。有关想法,请参阅 BioPerl

    【讨论】:

    • 感谢您的回复 G. Cito。我的想法是继续使用 R。
    • 如何打印是或否而不是 1,0?似乎您正在使用自动打印 1 或 0 的功能。
    • 由于 1 和 0 是布尔值,您可以将 print 语句更改为:( $paper{$_}{$category} ? print "yes " : print "no " ) ;。同样,要在输出中获得正确的格式,您需要使用printfperl formatsPDL(Perl 数据语言)或 R 之类的工具可能具有更多此类“内置”实用功能并可供使用。
    猜你喜欢
    • 1970-01-01
    • 2015-08-04
    • 2013-11-17
    • 1970-01-01
    • 2018-04-29
    • 2023-03-10
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多