首页 > 解决方案 > 如何对数据框中的行进行排序以获取 R 中某些列的最大净值和符号

问题描述

我有这个数据框

a <- c("5*", 7, 9, "11***")
b <- c("-8*", "-10*", -3, -1)
c <- c(-4, -1, "-6**", "3*")
df <- data.frame(a,b,c)
    a        b       c
1   5*      -8*     -4
2   7       -10*    -1
3   9       -3      -6**
4   11***   -1       3*

然后我希望这些行按照其中的最大净值排序(只考虑那些至少有一个“*”的值),独立于列。我的意思是,我期待这样的事情:

    a        b       c
4   11***   -1       3*
2   7       -10*    -1
1   5*      -8*     -4
3   9       -3      -6**


如您所见,它已排序,因为第一行的值为 11***,第二行 (-10*),第三行 (-8*),第四行 (-6**)。您可以注意到,在最后一行中,它在排序中省略了 9,这是因为我们只想考虑那些至少有一个“*”的数字

标签: rstringdataframesortingmatrix

解决方案


一种方法 -在后缀值中获取absolute ,基于这些值创建索引并使用它对行重新排序max*order

df[order(-apply(df, 1, FUN = function(x) 
       max(abs(as.numeric(sub("\\*+", "", x[grep("\\*", x)] )))))),]

-输出

    a    b    c
4 11***   -1   3*
2     7 -10*   -1
1    5*  -8*   -4
3     9   -3 -6**

或使用tidyverse, reshape to 'long' format with pivot_longer,filter只有元素具有*,arrange在数字部分通过提取 ( parse_number) ,slice原始的行基于排列的行号

library(dplyr)
library(stringr)
library(tidyr)
df %>%
    mutate(rn = row_number()) %>% 
    pivot_longer(cols = -rn) %>%
    filter(str_detect(value, fixed("*"))) %>%
    arrange(desc(abs(readr::parse_number(value)))) %>%
    distinct(rn) %>%
    pull(rn) %>%
    slice(df, .)

-输出

     a    b    c
1 11***   -1   3*
2     7 -10*   -1
3    5*  -8*   -4
4     9   -3 -6**

推荐阅读