【发布时间】:2018-07-26 17:51:42
【问题描述】:
我正在使用 perl 处理来自数据文件的大型数组,然后将它们放入 R 中以制作箱线图。这适用于小型数据集。但是,我想输入大型数据集以呈现给我的同事。 我想要一种方法来减少数据点的数量,并保持箱线图看起来相同(相同的最大值、最小值、四分位数等),因为 perl 会快速消耗内存(每个数据集大约 5GB 的 RAM),R 也是如此. 我确信对于目前 120GB 的问题有一个 10MB 的解决方案。
有没有办法减少数据大小,使其在箱线图中看起来相同在我将它放入 R 之前?我觉得自己很愚蠢,因为到目前为止我所做的仅适用于以下微不足道的小数据集:
#!/usr/bin/env perl
use strict; use warnings; use Cwd 'getcwd';
my $TOP_DIRECTORY = getcwd();
local $SIG{__WARN__} = sub {#kill the program if there are any warnings
my $message = shift;
my $fail_filename = "$TOP_DIRECTORY/$0.FAIL";
open my $fh, '>', $fail_filename or die "Can't write $fail_filename: $!";
printf $fh ("$message @ %s\n", getcwd());
close $fh;
die "$message\n";
};#http://perlmaven.com/how-to-capture-and-save-warnings-in-perl
sub reduce_size {#returns min, lower quartile, median, upper quartile, and max if > 5 elements
# R is not able to handle large arrays as Perl is. This subroutine reduces the work on R, which can't handle the size
#this does NOT work for means
my $x = shift;
# if (scalar @{ $x } < 6) {
# return @{ $x };
# }
my @sorted = sort {$a <=> $b} @{ $x };
my $n = scalar @{ $x };
my @return = $sorted[0];#minimum
if (($n % 2) == 0) {
$return[1] = $sorted[$n/4 ] ;
$return[2] = ($sorted[$n/2 - 1] + $sorted[$n/2])/2;
$return[3] = $sorted[3*$n/4 ] ;
} else {
my $i = sprintf("%.0f", $n/4);
$return[1] = ($sorted[ $i - 1] + $sorted[$i])/2;
$return[2] = $sorted[$n/2];
$i = sprintf("%.0f", 3*$n/4);
$return[3] = ($sorted[$i-1] + $sorted[$i])/2;
}
push @return, $sorted[-1];#maximum
return @return;
}
my @x = qw(-0.82312297 -0.08696213 2.23698132 0.20834949 0.73162884 0.22891093 1.04418464 -0.67952858 0.08111757);
my @y = reduce_size(\@x);
print join (',', @y) . "\n";
【问题讨论】:
-
您真的需要箱线图作为摘要,还是只显示一个统计表,例如您的
reduce_sizesub 中的那些?您还可以对其进行修改以生成与 R 中boxplot.stats()返回的相同值(即胡须、铰链),然后将它们列在表格中或根据这些值创建自定义图。 -
为什么要返回一个数组“return @return”。您应该返回数组引用。 “返回\@return”
-
@MarkS 确实,解决这个问题的方法就是简单翻译 R 的
fivenum函数
标签: r perl statistics