如何识别每行具有最大值的N列?

Ign*_*cio 1 r dplyr data.table

我的数据看起来像这样:

set.seed(122217)
df <- data.frame(ID = paste0("id",1:100), A = rnorm(100), E = rnorm(100), I = rnorm(100), O = rnorm(100), U = rnorm(100))
Run Code Online (Sandbox Code Playgroud)

我想生成一个包含100行和1 + 3列的新数据框.每行应对应于来自df的每个ID,第一列将是ID,而其他行将是First,Second,Third.

我可以用一些非常难看的代码来做到这一点:

library(data.table)
library(dplyr)
# transpose
t_df <- transpose(df[,2:6])
# get row and colnames in order
colnames(t_df) <- df[,1]
rownames(t_df) <- colnames(df[,2:6])
id_largest <-function(data, col){
  values <- data[,col]
  names(values) <- row.names(data)
  values <- sort(values, decreasing = T)
  ranking <- names(values)
  out <- data.frame( id= colnames(data)[col], First=ranking[1], Second=ranking[2], Third=ranking[3])
  return(out)
}

ranking <- purrr::map(1:ncol(t_df), id_largest, data=t_df) %>% rbindlist()
Run Code Online (Sandbox Code Playgroud)

这段代码产生了我想要的东西:

> head(ranking)
id First Second Third
1: id1     A      E     I
2: id2     U      O     I
3: id3     A      E     I
4: id4     E      U     I
5: id5     I      A     U
6: id6     I      A     U
Run Code Online (Sandbox Code Playgroud)

但不是很优雅.这样做有更干净的方法吗?

PoG*_*bas 6

解决方案apply:

 foo <- colnames(df)[-1]
 data.frame(df[, 1], 
            t(apply(df[, -1], 1, function(x) foo[tail(order(x), 3)]))[, 3:1])
Run Code Online (Sandbox Code Playgroud)