0

我想将这两个函数结合起来得到香农多样性指数。

怎么办?

第一个函数是使用 Data::Dumper 来获取唯一编号。

#!perl 

use warnings;
use strict;
use Data::Dumper;

$Data::Dumper::Sortkeys=1;    
my @names = qw(A A A A B B B C D);    
my %counts;
$counts{$_}++ for @names;    
printf "\$VAR1 = { %s};\n",       
join ' ',           
map "$_ ",             
sort { $b <=> $a }                
values(%counts);                
exit; 

这是输出

$VAR1 = { 4 3 1 1 };

然后我可以将它输入到第二个函数中。

第二个函数Statistics::Diversity::Shannon用于获取香农多样性指数。

#!perl

use warnings;   
use strict;    
use Statistics::Diversity::Shannon;

my @data = qw( 4 3 1 1 );    
my $d = Statistics::Diversity::Shannon->new( data => \@data );    
my $H = $d->index();    
my $E = $d->evenness();    
print "$d/$H/$E";    
exit;

如何通过使用原始数据集 (AAAABBBCD) 将这两个函数组合成一个完整的循环来获得香农多样性指数。

4

2 回答 2

3

Data::Dumper is a debugging tool, not a serializing too. Not a good one, at least.

But you aren't even using Data::Dumper. You're using something far worse.

Let's start by using something acceptable like JSON.

#!/usr/bin/perl 

use strict;
use warnings;

use Cpanel::JSON::XS qw( encode_json );

{
   my @names = qw( A A A A B B B C D );

   my %counts; ++$counts{$_} for @names;
   my @data = sort { $b <=> $a } values(%counts);

   print encode_json(\@data);
}

(Note that the sort { $b <=> $a } doesn't appear required.)

And this is one way to read it back in:

#!/usr/bin/perl 

use strict;
use warnings;

use Cpanel::JSON::XS               qw( decode_json );
use Statistics::Diversity::Shannon qw( );

{
   my $json = do { local $/; <> };
   my $data = decode_json($json);

   my $d = Statistics::Diversity::Shannon->new( data => $data );
   my $H = $d->index();
   my $E = $d->evenness();

   print "$H/$E\n";
}

Above, I assumed you meant "work together" when you said "combine into whole loop".

On the other hand, maybe you meant "combine into a single file". If that's the case, then you can use the following:

#!/usr/bin/perl 

use strict;
use warnings;

use Statistics::Diversity::Shannon qw( );

{
   my @names = qw( A A A A B B B C D );

   my %counts; ++$counts{$_} for @names;
   my @data = values(%counts);

   my $d = Statistics::Diversity::Shannon->new( data => \@data );
   my $H = $d->index();
   my $E = $d->evenness();

   print "$H/$E\n";
}
于 2019-12-16T04:01:21.610 回答
2

Your first code snippet does not use Data::Dumper correctly. Data::Dumper mainly provides one function, Dumper, which outputs any data in a format that can be interpreted as Perl code.

# instead of  printf "\$VAR1 = ...
print Dumper([values %counts]);

Since the output of Data::Dumper::Dumper is Perl code, you can read it by evaluating it as Perl code (with eval).

So if your first script writes output to a file called some.data, your second script can call

my $VAR1;
open my $fh, "<", "some.data";
eval do { local $/; <$fh> };      # read data from $fh and call  eval  on it
# now the data from the first script is in $VAR1
my $d = Statistics::Diversity::Shannon->new( data => $VAR1 );
...
于 2019-12-16T03:59:26.260 回答