R dataframe - 列名行中的前 n 个值

R dataframe - Top n values in row with column names

我想对特定列中的按行值进行排序,获取前 'n' 个值,并在新列中获取相应的列名。

输出看起来像这样:

      SL   SW    PL    PW   Species high1 high2 high3 col1 col2  col3
      dbl> <dbl> <dbl> <dbl> <fct>  <dbl> <dbl>  <dbl>
 1     5.1  3.5  1.4    0.2   setosa   3.5  1.4   0.2  SW   PL     PW
 2     4.9  3    1.4    0.2   setosa   3    1.4   0.2  SW   PL     PW
 3     4.7  3.2  1.3    0.2   setosa   3.2  1.3   0.2  SW   PL     PW

尝试了类似下面的代码,但无法获取列名。 我希望实现的是将最高 'n' 值(行 [n])与每一行数据框中的值进行比较,然后提取匹配值的相应列名。例如。行 [1] == 3.5(来自 'SW' 列)。这可行吗? 帮助表示赞赏。

 iris %>% 
      rowwise() %>%
      mutate(rows = list(sort(c( Sepal.Width, Petal.Length, Petal.Width), decreasing = TRUE))) %>%
      mutate(high1 = rows[1], col1 = names(~.)[which(~.[] ==rows[1]),
             high2 = rows[2], col2 = names(~.)[which(~.[] ==rows[2]),
             high3 = rows[3], col3 = names(~.)[which(~.[] ==rows[3])
             ) %>%
      select(-rows)

我的方法是创建一个函数,该函数接受任何数据框 (df)、您想要关注的任何一组列 (cols) 以及前 n 个值 (n)

# load data.table and magrittr (I only use %>% for illustration here)
library(data.table)
library(magrittr)

# define function
get_high_vals_cols <- function(df, cols, n=3) {
  
  setDT(df)[, `_rowid`:=.I]
  
  df_l <- melt(df,id = "_rowid",measure.vars = cols, variable.name = "col",value.name = "high") %>% 
    .[order(-high), .SD[1:n], by="_rowid"] %>% 
    .[,id:=1:.N, by="_rowid"]
  
  dcast(df_l, `_rowid`~id, value.var = list("col", "high"))[,`_rowid`:=NULL]
}

然后,您可以将任何数据框连同任何感兴趣的列一起提供给此函数

cols= c("Sepal.Width", "Petal.Length", "Petal.Width")
get_high_vals_cols(iris,cols,3)

输出

            col_1        col_2       col_3 high_1 high_2 high_3
  1:  Sepal.Width Petal.Length Petal.Width    3.5    1.4    0.2
  2:  Sepal.Width Petal.Length Petal.Width    3.0    1.4    0.2
  3:  Sepal.Width Petal.Length Petal.Width    3.2    1.3    0.2
  4:  Sepal.Width Petal.Length Petal.Width    3.1    1.5    0.2
  5:  Sepal.Width Petal.Length Petal.Width    3.6    1.4    0.2
 ---                                                           
146: Petal.Length  Sepal.Width Petal.Width    5.2    3.0    2.3
147: Petal.Length  Sepal.Width Petal.Width    5.0    2.5    1.9
148: Petal.Length  Sepal.Width Petal.Width    5.2    3.0    2.0
149: Petal.Length  Sepal.Width Petal.Width    5.4    3.4    2.3
150: Petal.Length  Sepal.Width Petal.Width    5.1    3.0    1.8

您可以转向长,按相应的原始行分组,使用 slice_max 获取最高值,然后转向回宽并将该输出绑定到原始 table。

library(dplyr, warn.conflicts = FALSE)
library(tidyr)

iris %>% 
  group_by(rn = row_number()) %>% 
  pivot_longer(-c(Species, rn), 'col', values_to = 'high') %>% 
  slice_max(col, n = 2) %>% 
  mutate(nm = row_number()) %>% 
  pivot_wider(values_from = c(high, col), 
              names_from = nm) %>% 
  ungroup() %>% 
  select(-c(Species, rn)) %>% 
  bind_cols(iris)
#> # A tibble: 150 × 9
#>    high_1 high_2 col_1   col_2 Sepal.Length Sepal.Width Petal.Length Petal.Width
#>     <dbl>  <dbl> <chr>   <chr>        <dbl>       <dbl>        <dbl>       <dbl>
#>  1    5.1    3.5 Sepal.… Sepa…          5.1         3.5          1.4         0.2
#>  2    4.9    3   Sepal.… Sepa…          4.9         3            1.4         0.2
#>  3    4.7    3.2 Sepal.… Sepa…          4.7         3.2          1.3         0.2
#>  4    4.6    3.1 Sepal.… Sepa…          4.6         3.1          1.5         0.2
#>  5    5      3.6 Sepal.… Sepa…          5           3.6          1.4         0.2
#>  6    5.4    3.9 Sepal.… Sepa…          5.4         3.9          1.7         0.4
#>  7    4.6    3.4 Sepal.… Sepa…          4.6         3.4          1.4         0.3
#>  8    5      3.4 Sepal.… Sepa…          5           3.4          1.5         0.2
#>  9    4.4    2.9 Sepal.… Sepa…          4.4         2.9          1.4         0.2
#> 10    4.9    3.1 Sepal.… Sepa…          4.9         3.1          1.5         0.1
#> # … with 140 more rows, and 1 more variable: Species <fct>

reprex package (v2.0.1)

创建于 2022-02-16

已编辑删除不必要的 renamemutate,感谢@Onyambu 的提示!