我有两个矩阵(例如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中完成吗?非常感谢提前
答案 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
中。一种解决方案是将intersect
与colnames(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