我有2个具有相同行名的矩阵,我发现了每行的前3个最小值(由于@ Maurits Evers)。现在,我需要找到3个最小值,但不要重复使用同名字符。我在计算最小值时需要唯一的ID,例如,如果Inst1选择Alt5作为最小值,则下一行(Inst2)不应选择相同的ID。因此,如果应该至少选择它们之前,我应该跳过,并寻找下一个最小值并报告它们。但是,如果第二行的最小值小于第一行的最小值,则第一行将替换为该特定行的下一个最小值。有什么建议吗?
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)))
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
#Expected output:
Inst Min1 1 Min2 2 Min3 3
Inst1 Ref4 0.0251 Alt2 0.228 Ref5 0.395375
Inst2 Alt5 0.110 Alt4 0.212 Alt1 0.380
Inst4 Ref3 0.00202 Alt3 0.0175 Ref1 0.289
答案 0 :(得分:0)
感谢您的提问和评论。有点僵硬的前向解决方案:让循环选择之前不存在的最小值,并记录先前选择的最小值以定义哪个是给定ID的最小值。对于格式化可以使用扩展功能
mindata <-as.data.frame(cbind.data.frame(X, Y) %>%
rownames_to_column("row") %>%
gather(Id, Minimum, -row) %>%
arrange(row, Minimum))
Pr_min <- c()
Def_min <- c()
par<-sum(mindata$row=="Inst1")
i<-1
for (row in unique(mindata$row)){
initial3 <- head(mindata[mindata$row==row & !(mindata$Id %in% Pr_min$Id), c(1:3) ], 3)
if(nrow(initial3)==0){next}
New_min <-mindata[(1 +(i-1)*par):max(rownames(initial3)), 2:3]
Pr_min <- rbind(Pr_min, initial3)
Def_min <- rbind(Def_min, New_min)
i <- i+1
}
Final <- Pr_min %>%
left_join((Def_min%>%
group_by(Id)%>%
summarise(min=min(Minimum))), by="Id")%>%
select(-Minimum)
CN <- rep(c("Min1", "Min2", "Min3"), ceiling(length(Final$Id)/3))[1:nrow(Final)]
Val_min <-Final%>% cbind( CN) %>% select(-Id)%>% spread(CN, min)
name_min <-Final%>% cbind( CN ) %>% select(-min)%>% spread(CN, Id)
cbind(name_min,Val_min[, 2:4])