从2个矩阵R中找到每一行的最小值

时间:2018-07-17 12:12:40

标签: r matrix

我需要2个矩阵中每行的最小值。行名称在两个矩阵中都是通用的,但列名称会更改。

例如:

matrix 1:
X <- matrix(runif(20), nrow=4)
rownames(X) <- paste0("Inst", seq(nrow(X)))
colnames(X) <- paste0("Ref", seq(ncol(X)))

matrix 2:
Y <- matrix(runif(20), nrow=4)
rownames(Y) <- paste0("Inst", seq(nrow(X)))
colnames(Y) <- paste0("Alt", seq(ncol(X)))

预期结果:

             Minimum    Id
    Inst1   0.1275317  Ref15
    Inst2   0.0006247  Alt4
    Inst3   0.04583117 Ref13
    Inst4   0.1111354  Alt5

我尝试了

t(apply(Y, 1, sort)[ 1, ]) 
t(apply(X, 1, sort)[ 1, ])

但是还不知道如何从两个矩阵中找到最小值并将其分别制表为预期的输出文件。另外,我有重复的行名和列名。

3 个答案:

答案 0 :(得分:2)

这里是tidyverse的可能性。请注意,我已经使用固定种子set.seed(2017)来生成示例数据。

library(tidyverse)
cbind.data.frame(X, Y) %>%
    rownames_to_column("row") %>%
    gather(Id, Minimum, -row) %>%
    group_by(row) %>%
    filter(Minimum == min(Minimum)) %>%
    arrange(row)
## A tibble: 4 x 3
## Groups:   row [4]
#  row   Id    Minimum
#  <chr> <chr>   <dbl>
#1 Inst1 Ref4  0.0251
#2 Inst2 Alt5  0.110
#3 Inst3 Ref2  0.0393
#4 Inst4 Ref3  0.00202

样本数据

set.seed(2017)
X <- matrix(runif(20), nrow=4)
rownames(X) <- paste0("Inst", seq(nrow(X)))
colnames(X) <- paste0("Ref", seq(ncol(X)))

Y <- matrix(runif(20), nrow=4)
rownames(Y) <- paste0("Inst", seq(nrow(Y)))
colnames(Y) <- paste0("Alt", seq(ncol(Y)))

更新

为回应您的评论,要保留前3名最低的条目,您可以使用top_n(如@Moody_Mudskipper的建议)

cbind.data.frame(X, Y) %>%
    rownames_to_column("row") %>%
    gather(Id, Minimum, -row) %>%
    group_by(row) %>%
    top_n(-3, Minimum) %>%
    arrange(row, Minimum)
## A tibble: 12 x 3
## Groups:   row [4]
#   row   Id    Minimum
#   <chr> <chr>   <dbl>
# 1 Inst1 Ref4  0.0251
# 2 Inst1 Alt3  0.0763
# 3 Inst1 Alt5  0.129
# 4 Inst2 Alt5  0.110
# 5 Inst2 Alt4  0.212
# 6 Inst2 Alt3  0.261
# 7 Inst3 Ref2  0.0393
# 8 Inst3 Alt5  0.177
# 9 Inst3 Ref1  0.469
#10 Inst4 Ref3  0.00202
#11 Inst4 Alt3  0.0175
#12 Inst4 Ref1  0.289

答案 1 :(得分:0)

您可以将矩阵与cbind合并,并与t()进行转置。然后,summarise_all中的dplyr可以为您提供每一行的最小值。

library(dplyr)
as.data.frame(t(cbind(X,Y))) %>% summarise_all(funs(min))
#        Inst1       Inst2       Inst3      Inst4
# 1 0.05845904 0.006901952 0.009513836 0.05197972

答案 2 :(得分:0)

使用来自@Maurits的样本数据,在基数R中:

XY <- cbind(X,Y)
wm_     <- apply(XY,1,which.min)
Minimum <- apply(XY,1,min)
data.frame(Minimum, id = colnames(XY)[wm_])
#           Minimum   id
# Inst1 0.025093514 Ref4
# Inst2 0.110404957 Alt5
# Inst3 0.039322336 Ref2
# Inst4 0.002020766 Ref3