在R中匹配和计数数据矩阵

3

数据集长这样:

 Gene SampleName
gene1    sample1
gene1    sample2
gene1    sample3
gene2    sample2
gene2    sample3
gene2    sample4
gene3    sample1
gene3    sample5

我的目标是创建一个这样的数据矩阵:

       gene1 gene2 gene3
gene1      -     2     1
gene2      -     -     0
gene3      -     -     -
gene1gene2的值为2,因为它们共享相同的样本sample2sample3gene1gene3的值为1,因为它们只共享一个相同的样本-sample1
我的问题是如何在R或Perl中实现这个目标?实际数据集要大得多。非常感谢您的帮助。
这是R的dput(df)输出:
df <- structure(list(Gene = c("gene1", "gene1", "gene1", "gene2", "gene2", 
"gene2", "gene3", "gene3"), SampleName = c("sample1", "sample2", 
"sample3", "sample2", "sample3", "sample4", "sample1", "sample5"
)), .Names = c("Gene", "SampleName"), row.names = c(NA, -8L), class = "data.frame")

你好sgibb,非常感谢你为我制作了这个格式。 - user3637642
当然,非常感谢您的评论。 - user3637642
2个回答

8

您可以查看crossprod(或tcrossprod)函数以及table

out <- tcrossprod(table(df))
out
#        Gene
# Gene    gene1 gene2 gene3
#   gene1     3     2     1
#   gene2     2     3     0
#   gene3     1     0     2

删除对角线和下三角,即可得到您所展示的精确输出。
diag(out) <- NA
out[lower.tri(out)] <- NA
print.table(out)  ## print.table deals with NAs differently
#        Gene
# Gene    gene1 gene2 gene3
#   gene1           2     1
#   gene2                 0
#   gene3                  

不错。我不知道 tcrossprod,也很少看到有人使用 crossprod,包括我自己。 - Rich Scriven
@Ananda,我很抱歉再次打扰你。这段代码对于示例来说非常完美。但当我尝试使用table(df)处理更大的数据集时,由于样本名称不是唯一的,导致计数不准确。您有任何想法,哪部分可能出了问题? - user3637642
@user3637642,你能用一个较小的数据集重新创建它,更新你的问题并在评论中@我吗?否则很难说。 - A5C1D2H2I1M1N2O1R2T1

2
perl -lane'
  $s{$F[0]}++ or push @k, $F[0];
  $h{$F[1]}{$F[0]} = 1;
END {
  $, = "\t";
  print "", @k;
  for $c (@k) {
    print $c, map {
      $u = $_;      
      ($c eq $u) ? "-" : scalar grep $_->{$c} && $_->{$u}, values %h;
    } @k;
  }
}
' file

输出

        gene1   gene2   gene3
gene1   -       2       1
gene2   2       -       0
gene3   1       0       -

2
相比于@Ananda的R答案,这看起来相当复杂。 - talat
3
@beginneR,我相信在R语言中也有看起来复杂但在其他编程语言中更简单的东西。 - A5C1D2H2I1M1N2O1R2T1
@beginneR 是的,它确实是另一种完全不同的语言(Perl缺少一些可以在R中找到的内建函数)。 - mpapec
1
当然,你们两个都是对的(而我对Perl一无所知)。只是注意到这个特定例子中的差异。我的意思不是说R > Perl。 - talat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接