Найти первый, второй и третий максимум каждой строки и соответствующие им имена столбцов в кадре данных в r - PullRequest
0 голосов
/ 02 января 2019

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

Вот как выглядит фрейм данных:

              X1    X2    X3   X4    X5   X6   X7    X8    X9    X10   X11  X12   
      10003   0.0   0.0   0.0  0.0   0.0  0.0  0.0   0.0   0.0   0.0   0.0  0.0       
      10006   0.0   0.0   0.0  0.0   0.0  0.0 16.7   0.0   0.0   0.0   0.0  0.0       
      10007   0.0   0.0   0.0  0.0   0.0  0.0  0.0   0.0   0.0   0.0   0.0  0.0       
      10008   0.0   0.0   0.0  0.0   0.0  0.0  0.0   0.0   0.0   0.0   0.0  0.0       
      10010   0.0   0.0   0.0  0.0   0.0  0.0  0.0   0.0   0.0   0.0   0.0  0.0       
      10014   0.0   0.0   0.0  0.0   0.0  0.0  0.0   0.0   0.0   0.0   0.0  0.0   

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Это пример данных, которые вы разместили в своем комментарии:

data <-read.table(text="       x1    x2    x3     x4    x5    x6   x7   x8    x9
                        1003    0  45.7     0   22.9     0  13.7    0    0  23.1 
                        1004 22.2     0  13.2      0   5.4     0  9.7    0     0 
                        1005    0     0     0     12   2.1     0    0  3.2     0  
                        1006  1.2     0   1.2      0  43.9  43.9    0    0  57.6",
                    header=T)

Вы можете использовать dplyr и tidyverse, чтобы добиться этого.


Следующий код даст вам максимум три столбца во всех строках:

library(dplyr)
library(tidyverse)

data %>% 
  rownames_to_column() %>%
  gather(column, value, -rowname) %>%
  group_by(rowname) %>% 
  arrange(desc(value)) %>% 
  head(3) 

Это даст вам следующий результат:

# A tibble: 3 x 3
# Groups:   rowname [3]
#   rowname column value
#   <chr>   <chr>  <dbl>
# 1 1006    x9      57.6
# 2 1003    x2      45.7
# 3 1006    x5      43.9

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

result <- data %>% 
  rownames_to_column() %>%
  gather(column, value, -rowname) %>%
  group_by(rowname) %>% 
  mutate(max = rank(-value)) %>%
  filter(max <= 3) %>% 
  arrange(rowname, max)

Что даст вам следующий результат:

# A tibble: 12 x 4
# Groups:   rowname [4]
#    rowname column value   max
#    <chr>   <chr>  <dbl> <dbl>
#  1 1003    x2      45.7   1  
#  2 1003    x9      23.1   2  
#  3 1003    x4      22.9   3  
#  4 1004    x1      22.2   1  
#  5 1004    x3      13.2   2  
#  6 1004    x7       9.7   3  
#  7 1005    x4      12     1  
#  8 1005    x8       3.2   2  
#  9 1005    x5       2.1   3  
# 10 1006    x9      57.6   1  
# 11 1006    x5      43.9   2.5
# 12 1006    x6      43.9   2.5

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

result %>% 
  mutate(result = paste0(column, "=", value, collapse = ", ")) %>% 
  select(result) %>% 
  distinct()

Что даст вам следующий результат:

# A tibble: 4 x 2
# Groups:   rowname [4]
#   rowname result                   
#   <chr>   <chr>                    
# 1 1003    x2=45.7, x9=23.1, x4=22.9
# 2 1004    x1=22.2, x3=13.2, x7=9.7 
# 3 1005    x4=12, x8=3.2, x5=2.1    
# 4 1006    x9=57.6, x5=43.9, x6=43.9


Надеюсь, это поможет.

0 голосов
/ 02 января 2019

Вы можете использовать

max.names = apply(data, 1, function(x) names(sort(x, decreasing = T)[1:3]))
max.vals = apply(data, 1, function(x) sort(x, decreasing = T)[1:3])
data = cbind(data, t(max.names), t(max.vals))
#        x1   x2   x3   x4   x5   x6  x7  x8   x9  1  2  3    1    2    3
# 1003  0.0 45.7  0.0 22.9  0.0 13.7 0.0 0.0 23.1 x2 x9 x4 45.7 23.1 22.9
# 1004 22.2  0.0 13.2  0.0  5.4  0.0 9.7 0.0  0.0 x1 x3 x7 22.2 13.2  9.7
# 1005  0.0  0.0  0.0 12.0  2.1  0.0 0.0 3.2  0.0 x4 x8 x5 12.0  3.2  2.1
# 1006  1.2  0.0  1.2  0.0 43.9 43.9 0.0 0.0 57.6 x9 x5 x6 57.6 43.9 43.9
0 голосов
/ 02 января 2019

Вот мой подход:

 # Make up data because yours is pretty unreproducible:
 df <- data.frame(X1=1:5, X2=c(3,5,1,6,7))

 # combine and sort the data by decreasing value:
 a <- sort(dplyr::combine(df), decreasing = T)[1:3]

 # For loop to get the indexes:
 for(i in 1:length(a)){
    print(which(df==a[i], arr.ind = T))
 }

Это даст вам то, что вам нужно. Замените print тем, что вы хотите сделать (например, назначить или что вам нужно)

...