首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >tidyverse计算几个列的每行排序

tidyverse计算几个列的每行排序
EN

Stack Overflow用户
提问于 2020-08-21 18:50:24
回答 2查看 363关注 0票数 3

我有以下数据框架:

代码语言:javascript
运行
复制
dat <- data.frame(id = c("a", "b", "c", "d"),
                  x1 = c(1, 3, 5, 7),
                  x2 = c(4, 2, 6, 0),
                  x3 = c(2, 2, 5, 9))

现在,我想计算我的三个x列的每行排名,并将结果存储到我的dat数据框架中。因此,结果可以通过两种方式存储:

( a)理想情况下,会有4支新的列,各自的职级或

( b)将有一个新的嵌套列,我可能需要以某种方式取消嵌套。

我尝试了下面的方法,这至少给了我一个列表列。

代码语言:javascript
运行
复制
dat %>%
  rowwise() %>%
  mutate(my_ranks = list(rank(c_across(starts_with("x")))))

但是当我尝试去嵌套时,它会给我排名,但是它会创建新的行(即每个原始的大小写现在出现四次)。虽然我想我可以用pivot_wider来重塑这个结果,但走这条路是不对的。

有什么更好/更容易的主意吗?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-21 21:28:12

我们可以使用unnest_wider

代码语言:javascript
运行
复制
library(dplyr)
library(tidyr)
library(stringr)
dat %>%
   rowwise() %>%
   mutate(my_ranks = list(rank(c_across(starts_with("x"))))) %>%
   unnest_wider(c(my_ranks)) %>%
   rename_at(vars(starts_with("...")), ~ str_replace(., fixed("..."), "rank_x"))
# A tibble: 4 x 7
#  id       x1    x2    x3  rank_x1 rank_x2 rank_x3
#  <chr> <dbl> <dbl> <dbl>    <dbl>    <dbl>    <dbl>
#1 a         1     4     2      1        3        2  
#2 b         3     2     2      3        1.5      1.5
#3 c         5     6     5      1.5      3        1.5
#4 d         7     0     9      2        1        3  

另一个选择是pmap/as_tibble_row

代码语言:javascript
运行
复制
library(tibble)
library(purrr)
dat %>% 
     mutate(my_ranks = pmap(select(., starts_with('x')), ~ 
           as_tibble_row(rank(c(...)),
            .name_repair = ~ str_c('rank', seq_along(.))))) %>%
     unnest(c(my_ranks))
# A tibble: 4 x 7
#  id       x1    x2    x3 rank1 rank2 rank3
#  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 a         1     4     2   1     3     2  
#2 b         3     2     2   3     1.5   1.5
#3 c         5     6     5   1.5   3     1.5
#4 d         7     0     9   2     1     3  

使用来自rowRanksmatrixStats可以完成更简单的工作。

代码语言:javascript
运行
复制
library(matrixStats)
nm1 <- names(dat)[-1]
dat[paste0('rank', nm1)] <- rowRanks(as.matrix(dat[nm1]), ties.method = 'average')
票数 6
EN

Stack Overflow用户

发布于 2020-08-21 21:27:33

我想这是一种潮流:

代码语言:javascript
运行
复制
dat %>%
  bind_cols(as_tibble(`colnames<-`(t(apply(dat[-1], 1, rank)), paste0("rank_x", 1:3))))
#>   id x1 x2 x3 rank_x1 rank_x2 rank_x3
#> 1  a  1  4  2     1.0     3.0     2.0
#> 2  b  3  2  2     3.0     1.5     1.5
#> 3  c  5  6  5     1.5     3.0     1.5
#> 4  d  7  0  9     2.0     1.0     3.0
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63528545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档