首页 > 解决方案 > 创建一个用交叉减法填充的对称矩阵

问题描述

我有以下制表符分隔的文件:

Oslo      5
Montreal  4
Berlin    7
London    7
...

根据该数据,我正在尝试构建一个对称表,其中填充了所有 x 之间的减法,生成如下表:

          Oslo      Montreal  Berlin    London
          --------- --------- --------- ---------
Oslo              0        -1         2         2
Montreal          1         0         3         3
Berlin           -2        -3         0         0
London           -2        -3         0         0

输出应该是一个制表符分隔的文件。

我一直在尝试用 R 和 perl 来做这件事,我有基本的经验,但我都做不到。在 Perl 中,我尝试使用 hash 来做减法,但我还是一无所有。我认为 Python 应该有一个很好的解决方案,但我从未尝试过编写 Python 脚本,我才刚刚开始。我使用几个不同的关键字组合在谷歌中寻找它,我发现的独特的类似案例是这样的,但是用另一种语言: 创建对称矩阵

请你帮助我好吗?将不胜感激!

PS:由于我的问题可能太浅了,你至少可以建议我用什么语言(R、Perl 或 Python)、函数、包甚至是一些更合适的关键字来继续尝试解决我自己。

我试过这个来得到所有 x 所有减法,但我肯定在这里迷路了:

#!/usr/bin/perl
use diagnostics;
use warnings;

print "file:\t";
$arq1 = <STDIN>;
open (MYFILE, $arq1);
my %hash;
while (my $line=<MYFILE>) {
    chomp($line);
    (my $city,my $value) = split /\t/, $line;
    $hash{$city} = $value;
}

my %hash2;
while (my $line=<MYFILE>) {
    chomp($line);
    (my $city,my $value) = split /\t/, $line;
    $hash2{$city} = $value;
}

my @diff;
foreach my $key (keys %hash) {
    @diff = $hash{$key} - $hash2{$key};
}

print "difference @diff\n";

标签: rperlmatrix

解决方案


这是 R 中的一个解决方案。也许不是最干净的,但它是一个:

library(dplyr)
library(magrittr)

df <- data.frame(city = c("Oslo","Paris","Londres","Lima","Lyon","Memphis","Ouagadougou"),
                 pop = runif(7, min = 5000, max = 10000))

result <- data.frame(matrix(nrow = nrow(df), ncol = nrow(df)))
names(result) <- df$city
row.names(result) <- df$city

for(city in df$city) {
  tmp <- df$pop - df$pop[df$city == city]
  result[,as.character(city)] <- tmp
}

接下来的三行允许将行名转换为经典列:

result$city <- row.names(result)
row.names(result) <- 1:nrow(result)
result2 <- result %>% dplyr::select(city, everything())

推荐阅读