Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
199 views
in Technique[技术] by (71.8m points)

non-character argument error from Perl sub, but works in R

I have a trivial R script that works nicely:

library(gplots)
A <- c("dog", "cat", "monkey", "fish", "cow", "frog")
B <- c("cat", "frog", "aardvark", "monkey", "cow", "lizard", "bison", "goat")

png('tmp.png')
venn(list(A=A,B=B))

and am trying to write a perl subroutine that will do the above action in R using the Statistics::R package:

#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';
use feature 'say';
use autodie ':all';
use Carp 'confess';
use Statistics::R;

my @t1 = ("dog", "cat", "monkey", "fish", "cow", "frog");
my @t2 = ("cat", "frog", "aardvark", "monkey", "cow", "lizard", "bison", "goat");
my %data = (
    A => [@t1],
    B => [@t2]
);
sub venn {
    my ($args) = @_;
    unless (defined $args->{output_filestem}) {
        confess "venn diagram needs an output filename" 
    }
    if (scalar keys %{ $args->{data} } < 2) {
        printf("There are %u keys in data.
", scalar keys %{ $args->{data} });
        confess 'There must be >= 2 keys in data.';
    }
    my $R = Statistics::R->new();
    foreach my $key (keys %{ $args->{data} }) {
        $R -> set("$key", $args->{data}{key});
    }
    say __LINE__;
    if (defined $args->{output_type}) {
        $R -> run(`$args->{output_type}('$args->{output_stem}.$args->{output_type}')`);
    } else { # output EPS file is default
        $args->{output_type} = 'eps';
        $R -> run(
            q`setEPS()`,
            qq`postscript('$args->{output_filestem}.eps')`,
        );
    }
    my @venn;
    foreach my $key (sort keys %{ $args->{data} }) {
        push @venn, "$key=$key"
    }
    my $venn_cmd = 'venn(list(' . join (', ', @venn) . '))';
    say $venn_cmd;
    $R -> run(q`library(gplots)`);
    $R -> run(qq`$venn_cmd`);
    say "wrote $args->{output_filename}";
    return $args->{output_filename}
}

venn({
    data => \%data,
    output_filestem => 'venn'
});

but running this Perl script produces an error:

venn(list(A=A, B=B))

Error:
strsplit(names(map), character(0), fixed = TRUE) : 
  non-character argument
Calls: venn -> vennMembers -> do.call -> strsplit
Execution halted
Command exited with non-zero status 29

Something similar is in Non character argument in R string split function (strsplit) but I don't see how to apply what's there to my case.

Maybe this is some error in Statistics::R? The input the Perl sub should be identical to the R script.

and I have no idea what causes this, because the R commands that I'm using are identical to the working R script.

Why does the Perl sub fail, even when it does the exact same as the R script?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Missing sigil:

$R -> set("$key", $args->{data}{key});

should be

$R -> set("$key", $args->{data}{$key});
#                               ^

Otherwise, the A and B are populated with undef which leads to the error.

BTW, "$key" is the same as $key. There's no need to doublequote a variable.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...