I need the minimum value for each rows from 2 matrix. The row names are common in both matrix but the column name changes.
eg:
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)))
Expected result:
Minimum Id
Inst1 0.1275317 Ref15
Inst2 0.0006247 Alt4
Inst3 0.04583117 Ref13
Inst4 0.1111354 Alt5
I tried
t(apply(Y, 1, sort)[ 1, ])
t(apply(X, 1, sort)[ 1, ])
Yet don't know how to find the minimum from both matrix and tabulate separately as expected output file. Also I have duplicated rownames and colnames.
Here is a tidyverse
possibility. Note that I've used the fixed seed set.seed(2017)
for the generation of sample data.
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)))
In response to your comment, to retain the top 3 lowest entries you can use top_n
(as suggested by @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
You can combine your matrix with cbind
and transpose it with t()
. Then a summarise_all
from dplyr
could give you a min for each row.
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
Using sample data from @Maurits, in base 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.