2017-02-23 98 views
1

У меня есть матрица вроде этого:Как извлечь имена столбцов, которые соответствуют наибольшим из трех чисел в каждой строке в матрице?

x <- matrix(rnorm(100), nrow = 10) 
colnames(x) <- combn(letters[1:8], 2, FUN = paste0, collapse = '')[seq_len(ncol(x))] 

Я хочу, чтобы извлечь COLNAMES которые наибольшие три числа в каждой строке соответствуют. Я пытаюсь использовать следующий код, чтобы решить эту проблему:

apply(x,1,function(x) order(x,decreasing=T)[1:3]) 

или

apply(x,1,function(x) x[order(x,decreasing=T)[1:3]]) 

Но я только извлечь значение или номера столбцов, а не colnames.Futher, если я хочу, ценности и COLNAMES как в ячейку в матрице размером 3 × 10 и каждую ячейку, такую ​​как: (значение, ее имя colname), как мне улучшить код?

ответ

2

Вы вызываете значения, а не имена, в своем обращении.

Использование

t(apply(x,1,function(x) names(x[order(x, decreasing = T)])[1:3])) 

получить

 [,1] [,2] [,3] 
[1,] "ac" "ae" "bc" 
[2,] "ah" "ae" "bd" 
[3,] "ab" "ad" "ah" 
[4,] "ah" "ae" "ag" 
[5,] "bc" "ac" "ab" 
[6,] "ad" "be" "ah" 
[7,] "ag" "be" "ah" 
[8,] "be" "bd" "ag" 
[9,] "ae" "ad" "bc" 
[10,] "ac" "ad" "bc" 

Чтобы объединить значения и COLNAMES, сделайте следующее:

mymatrix <- t(matrix(paste(apply(x,1,function(x) x[order(x,decreasing=T)[1:3]]), 
         apply(x,1,function(x) names(x[order(x, decreasing = T)])[1:3]), 
         sep = ", "), nrow = 3)) 

Выход:

 [,1]     [,2]     [,3]     
[1,] "1.59913311795783, ac" "0.885534156178676, ae" "0.875246820694047, bc" 
[2,] "1.88262373384617, ah" "0.872567862286068, ae" "0.660631089010629, bd" 
[3,] "1.49244514568881, ab" "1.35311293758955, ad" "0.394056724464136, ah" 
[4,] "2.32470081848151, ah" "1.50673571308499, ae" "0.447576219573032, ag" 
[5,] "1.51100753431057, bc" "0.977989261628962, ac" "0.943834483720892, ab" 
[6,] "1.73431308924992, ad" "1.19278829328726, be" "0.718634846412602, ah" 
[7,] "0.930041809046426, ag" "0.800971669579496, be" "0.35523503674387, ah" 
[8,] "0.759183586558264, be" "0.284400004143193, bd" "0.16139357971149, ag" 
[9,] "1.45860700391869, ae" "0.767188128292325, ad" "0.760496361266797, bc" 
[10,] "1.89419796606409, ac" "1.1554236572704, ad" "0.850762486867097, bc" 
2

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

> y <- t(apply(x, 1, order, decreasing=TRUE)[1:3,]) 

Затем построить массив, который может быть использован в качестве индекса на x для извлечения значений

> i <- cbind(1:nrow(x), c(y)) 

Теперь получить имена столбцов и соответствующие значения

> cnames <- replace(y, TRUE, colnames(x)[i[,2]]) 
> values <- replace(y, TRUE, x[i]) 

Наконец объединить два

> replace(y, TRUE, sprintf('(% .3f,%s)', c(values), c(cnames))) 
     [,1]   [,2]   [,3]   
[1,] "(1.633,ac)" "(1.277,ad)" "(0.609,bc)" 
[2,] "(0.660,bd)" "(0.269,be)" "(0.184,ab)" 
[3,] "(0.970,ae)" "(0.698,ag)" "(0.204,ac)" 
[4,] "(1.014,ac)" "(0.158,ad)" "(0.090,af)" 
[5,] "(1.481,ae)" "(0.975,ad)" "(0.035,ag)" 
[6,] "(2.007,ag)" "(0.823,bd)" "(0.699,be)" 
[7,] "(2.019,ag)" "(1.535,be)" "(1.273,bd)" 
[8,] "(1.972,ah)" "(1.320,ac)" "(0.878,be)" 
[9,] "(2.261,ae)" "(0.972,af)" "(0.422,bc)" 
[10,] "(1.434,ad)" "(0.979,af)" "(0.527,bd)"