Выбрать строку с наибольшим значением и вернуть имя строки - PullRequest
2 голосов
/ 02 февраля 2020

Для каждого столбца я хотел бы выбрать имя строки, которое имеет самое высокое значение во всех строках. Пожалуйста, посмотрите мой пример ввода и вывода.

> df.t[,1:5][1:5,]
                MMRF_1021 MMRF_1024 MMRF_1029 MMRF_1030 MMRF_1031
ENSG00000004468  8.195680  7.500753  7.912472  8.886945  6.780892
ENSG00000081237  4.401101  6.135663  6.525512  4.496787  7.927844
ENSG00000139193  6.124573  6.585169  5.547023  6.254043  2.764494
ENSG00000156738 -1.491527  2.237000  7.192401  8.032151 -4.253239
ENSG00000174059 -5.663732 -4.477220 -5.663732 -4.237282 -4.792564

out

MMRF_1021 ENSG00000004468
MMRF_1024 ENSG00000004468
MMRF_1029 ENSG00000004468 
MMRF_1030 ENSG00000004468
MMRF_1031 ENSG00000081237 

Ответы [ 2 ]

1 голос
/ 02 февраля 2020

Мы можем преобразовать фрейм данных и использовать max.col

data.frame(col = names(df), value  = rownames(df)[max.col(t(df))])

#        col           value
#1 MMRF_1021 ENSG00000004468
#2 MMRF_1024 ENSG00000004468
#3 MMRF_1029 ENSG00000004468
#4 MMRF_1030 ENSG00000004468
#5 MMRF_1031 ENSG00000081237

data

df <- structure(list(MMRF_1021 = c(8.19568, 4.401101, 6.124573, -1.491527, 
-5.663732), MMRF_1024 = c(7.500753, 6.135663, 6.585169, 2.237, 
-4.47722), MMRF_1029 = c(7.912472, 6.525512, 5.547023, 7.192401, 
-5.663732), MMRF_1030 = c(8.886945, 4.496787, 6.254043, 8.032151, 
-4.237282), MMRF_1031 = c(6.780892, 7.927844, 2.764494, -4.253239, 
 -4.792564)), class = "data.frame", row.names = c("ENSG00000004468", 
"ENSG00000081237", "ENSG00000139193", "ENSG00000156738", "ENSG00000174059"))
0 голосов
/ 02 февраля 2020

В этом случае получите максимальный индекс столбца с максимальным значением с помощью sapply, преобразуйте именованный vector в data.frame с двумя столбцами (stack) и transform индекс в имена строк, используя этот индекс как цифра c индекс

transform(stack(sapply(df.t, which.max))[2:1], values = row.names(df.t)[values])
#   ind          values
#1 MMRF_1021 ENSG00000004468
#2 MMRF_1024 ENSG00000004468
#3 MMRF_1029 ENSG00000004468
#4 MMRF_1030 ENSG00000004468
#5 MMRF_1031 ENSG00000081237

Или сделать его немного более компактным

stack(lapply(df.t, function(x) row.names(df.t)[which.max(x)]))

Или использовать max.col с stack

stack(setNames(row.names(df.t)[max.col(t(df.t))],  names(df.t)))[2:1]
#      ind          values
#1 MMRF_1021 ENSG00000004468
#2 MMRF_1024 ENSG00000004468
#3 MMRF_1029 ENSG00000004468
#4 MMRF_1030 ENSG00000004468
#5 MMRF_1031 ENSG00000081237

Аналогичная опция в tidyverse будет использовать summarise_all до l oop для всех столбцов, получить индекс с помощью which.max, преобразовать в двух столбец data.frame и изменить индекс

library(dplyr)
library(tidyr)
df.t %>% 
   summarise_all(which.max) %>%
   pivot_longer(everything()) %>%
   mutate(value = row.names(df.t)[value])

Или мы можем избежать последнего шага с помощью

df.t %>%
   summarise_all(~ row.names(df.t)[which.max(.)]) %>%
   pivot_longer(everything())

Или другой вариант - сначала выполнить pivot_longer, а затем выполнить группировку с помощью операции

df.t %>% 
   pivot_longer(everything()) %>% 
   group_by(name) %>% 
   summarise(value = row.names(df.t)[which.max(value)])

или используя map с enframe

library(purrr)
library(tibble)
map(df.t, ~ row.names(df.t)[which.max(.x)]) %>%
     enframe %>%
     unnest(c(value))

data

df.t <- structure(list(MMRF_1021 = c(8.19568, 4.401101, 6.124573, -1.491527, 
-5.663732), MMRF_1024 = c(7.500753, 6.135663, 6.585169, 2.237, 
-4.47722), MMRF_1029 = c(7.912472, 6.525512, 5.547023, 7.192401, 
-5.663732), MMRF_1030 = c(8.886945, 4.496787, 6.254043, 8.032151, 
-4.237282), MMRF_1031 = c(6.780892, 7.927844, 2.764494, -4.253239, 
-4.792564)), class = "data.frame", row.names = c("ENSG00000004468", 
"ENSG00000081237", "ENSG00000139193", "ENSG00000156738", "ENSG00000174059"
))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...