后续:重新排序对称标题 [英] Follow-up: Re-ordering a symmetric tibble

查看:27
本文介绍了后续:重新排序对称标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在跟进这个很棒的答案.特别是,我想知道如何将输出的第一列的值(实际上是行名)与其余列名重新排序?

I'm following up on this great answer. In particular, I was wondering how to re-order the output's first columns' values (which are really rownames) with the rest of the columnames?

有人建议我两种解决方案,但这两种解决方案似乎在函数中不起作用.这个问题有tidyverse解决方案吗?

I was suggested two solutions but it seems these two solutions don't work in the function. Is there a tidyverse solution to this problem?

foo <- function(data, study_id, ...){
  
   study_id <- rlang::ensym(study_id)
   cat_mod <- rlang::ensyms(...)
   purrr::map(cat_mod,  ~ {
  
   studies_cats <- 
     data %>%
     dplyr::group_by(!!study_id, !!.x) %>%
     dplyr::summarise(effects = n(), .groups = 'drop')
     nm1 <- rlang::as_string(.x)
     cat_names <- paste0(nm1, c(".x", ".y"))
    studies_cats <- 
      studies_cats %>%
      dplyr::inner_join(studies_cats, by = rlang::as_string(study_id)) %>%
      dplyr::group_by(!!!rlang::syms(cat_names)) %>%
      dplyr::summarise(
        studies = n(),
        effects = sum(effects.x), .groups = 'drop') %>% 
      dplyr::mutate(n = paste0(studies, " (", effects, ")") )

    studies_cats %>%
      dplyr::select(-studies, -effects) %>%
      tidyr::pivot_wider(names_from = cat_names[2], values_from = n) %>%
      dplyr::rename_with(~nm1,  cat_names[1]) })}

# EXAMPLE OF USE (notice columnames are ordered `0,1,10,2,3` but 
# first column values are ordered: `0,1,2,3,10`):

d <- read.csv("https://raw.githubusercontent.com/rnorouzian/s/main/w7_smd_raw.csv")
foo(data, study, error.type)

#  error.type `0`      `1`      `10`   `2`    `3`   
#  <fct>      <chr>    <chr>    <chr>  <chr>  <chr> 
#1 0          27 (189) 1 (6)    1 (2)  NA     NA    
#2 1          1 (18)   16 (118) 2 (10) 2 (6)  2 (6) 
#3 2          NA       2 (6)    NA     6 (33) 2 (6) 
#4 3          NA       2 (6)    NA     2 (6)  5 (27)
#5 10         1 (2)    2 (22)   6 (48) NA     NA   

推荐答案

pivot_wider 创建列顺序的行为基于相同的 unique 值出现顺序来自默认指定的 names_to 列(因为 names_sort = FALSE).如果我们想让订单动态化,那么一种选择是先排列列(这是数字).执行 arrange 也使事情更加灵活,即假设我们只想根据子字符串(即数字部分)进行排序,可以提取这些并执行顺序,而在 names_sort 中可能不会就是这样

pivot_wider behavior of creating the order of columns is based on the same order of unique appearance of values from the names_to column specified by default (because names_sort = FALSE). If we want to make the order dynamic, then one option is to arrange the column first (which is numeric). Doing the arrange also makes things more flexible i.e. suppose we want to order only based on a substring i.e. numeric part, can extract those and do the order whereas in names_sort that may not be the case

foo <- function(data, study_id, ...){
  
     study_id <- rlang::ensym(study_id)
     cat_mod <- rlang::ensyms(...)
     purrr::map(cat_mod,  ~ {
  
     studies_cats <- 
       data %>%
       dplyr::group_by(!!study_id, !!.x) %>%
       dplyr::summarise(effects = n(), .groups = 'drop')
       nm1 <- rlang::as_string(.x)
       cat_names <- paste0(nm1, c(".x", ".y"))
      studies_cats <- 
        studies_cats %>%
        dplyr::inner_join(studies_cats, by = rlang::as_string(study_id)) %>%
        dplyr::group_by(!!!rlang::syms(cat_names)) %>%
        dplyr::summarise(
          studies = n(),
          effects = sum(effects.x), .groups = 'drop') %>% 
        dplyr::mutate(n = paste0(studies, " (", effects, ")") )

      studies_cats %>%
        dplyr::select(-studies, -effects) %>%
        dplyr::arrange(across(all_of(cat_names[2]))) %>%
        tidyr::pivot_wider(names_from = cat_names[2], values_from = n) %>%
        dplyr::rename_with(~nm1,  cat_names[1])  %>%
        dplyr::arrange(across(all_of(nm1))) %>%
        dplyr::mutate(across(all_of(nm1), as.character))
        
          })
        }

-输出

foo(d, study, error.type)
[[1]]
# A tibble: 5 x 6
  error.type `0`      `1`      `2`    `3`    `10`  
  <chr>      <chr>    <chr>    <chr>  <chr>  <chr> 
1 0          27 (189) 1 (6)    <NA>   <NA>   1 (2) 
2 1          1 (18)   16 (118) 2 (6)  2 (6)  2 (10)
3 2          <NA>     2 (6)    6 (33) 2 (6)  <NA>  
4 3          <NA>     2 (6)    2 (6)  5 (27) <NA>  
5 10         1 (2)    2 (22)   <NA>   <NA>   6 (48)


或者也可以使用names_sort = TRUE

foo <- function(data, study_id, ...){
  
       study_id <- rlang::ensym(study_id)
       cat_mod <- rlang::ensyms(...)
       purrr::map(cat_mod,  ~ {
  
       studies_cats <- 
         data %>%
         dplyr::group_by(!!study_id, !!.x) %>%
         dplyr::summarise(effects = n(), .groups = 'drop')
         nm1 <- rlang::as_string(.x)
         cat_names <- paste0(nm1, c(".x", ".y"))
        studies_cats <- 
          studies_cats %>%
          dplyr::inner_join(studies_cats, by = rlang::as_string(study_id)) %>%
          dplyr::group_by(!!!rlang::syms(cat_names)) %>%
          dplyr::summarise(
            studies = n(),
            effects = sum(effects.x), .groups = 'drop') %>% 
          dplyr::mutate(n = paste0(studies, " (", effects, ")") )

        studies_cats %>%
          dplyr::select(-studies, -effects) %>%        
          tidyr::pivot_wider(names_from = cat_names[2], 
                values_from = n, names_sort = TRUE) %>%
          dplyr::rename_with(~nm1,  cat_names[1])  %>%
          dplyr::arrange(across(all_of(nm1))) %>%
          dplyr::mutate(across(all_of(nm1), as.character))
        
            })
          }

-输出

> foo(d, study, error.type)
[[1]]
# A tibble: 5 x 6
  error.type `0`      `1`      `2`    `3`    `10`  
  <chr>      <chr>    <chr>    <chr>  <chr>  <chr> 
1 0          27 (189) 1 (6)    <NA>   <NA>   1 (2) 
2 1          1 (18)   16 (118) 2 (6)  2 (6)  2 (10)
3 2          <NA>     2 (6)    6 (33) 2 (6)  <NA>  
4 3          <NA>     2 (6)    2 (6)  5 (27) <NA>  
5 10         1 (2)    2 (22)   <NA>   <NA>   6 (48)

这篇关于后续:重新排序对称标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆