按列连接两个矩阵并提取子矩阵

时间:2013-04-07 10:32:16

标签: r perl matrix subset

我有两个矩阵(例如A和B)。我想根据A的第一列的顺序提取B的列:

例如

矩阵A

name score
a 0.1
b 0.2
c 0.1
d 0.6

矩阵B

a    d   b   c   g   h
0.1 0.2 0.3 0.4 0.6 0.2
0.2 0.1 0.4 0.7 0.1 0.1
...

我希望矩阵B在最后看起来像这样

矩阵B_modified

a    b   c   d
0.1 0.3 0.4 0.2
0.2 0.4 0.7 0.1

这可以在perl或R中完成吗?非常感谢提前

3 个答案:

答案 0 :(得分:2)

我不知道你面临的问题是什么。我就是这样做的。

## get data as matrix
a <- read.table(header=TRUE, text="name score
a 0.1
b 0.2
c 0.1
d 0.6", stringsAsFactors=FALSE) # load directly as characters

b <- read.table(header=TRUE, text="a    d   b   c   g   h
0.1 0.2 0.3 0.4 0.6 0.2
0.2 0.1 0.4 0.7 0.1 0.1", stringsAsFactors=FALSE)

a <- as.matrix(a)
b <- as.matrix(b)

现在是子集以获得最终结果:

b[, a[, "name"]]
#        a   b   c   d
# [1,] 0.1 0.3 0.4 0.2
# [2,] 0.2 0.4 0.7 0.1

答案 1 :(得分:2)

错误:

[.data.frame(b, , a[, "name"]) : undefined columns selected

表示您尝试获取b中未定义的列,但存在于a$name中。一种解决方案是将intersectcolnames(b)一起使用。这也会将因子转换为字符串,并获得正确的顺序。

b[, intersect(a[, "name"],colnames(b))] ## the order is important here 

例如,我用这些数据测试:

b <- read.table(text='
a    d   b   c
0.1 0.2 0.3 0.4
0.2 0.1 0.4 0.7',header=TRUE)

a <- read.table(text='name score
a 0.1
z 0.5
c 0.1
d 0.6',header=TRUE)

b[, intersect(a[, "name"],colnames(b))]


    a   c   d
1 0.1 0.4 0.2
2 0.2 0.7 0.1

答案 2 :(得分:2)

如果您的数据源自R数据结构,那么导出它并使用Perl解决此问题将是不正常的。但是,如果您的文本文件看起来与您显示的数据类似,那么这里有一个Perl解决方案。

我已将输出拆分为空格。如果有必要,可以非常简单地改变。

use strict;
use warnings;
use autodie;

sub read_file {
  my ($name) = @_;
  open my $fh, '<', $name;
  my @data = map [ split ], <$fh>;
  \@data;
}

my $matrix_a = read_file('MatrixA.txt');
my @fields = map $matrix_a->[$_][0], 1 .. $#$matrix_a;

my $matrix_b = read_file('MatrixB.txt');
my @headers = @{$matrix_b->[0]};
my @indices = map {
  my $label = $_;
  grep $headers[$_] eq $label, 0..$#headers
} @fields;

for my $row (0 .. $#$matrix_b) {
  print join('  ', map $matrix_b->[$row][$_], @indices), "\n";
}

<强>输出

a  b  c  d
0.1  0.3  0.4  0.2
0.2  0.4  0.7  0.1