后续:重新排序一个对称的tibble
Follow-up: Re-ordering a symmetric tibble
我正在跟进 。特别是,我想知道如何将输出的第一列值(实际上是行名)与其余列名一起重新排序?
我被建议 但是这两个解决方案似乎在函数中不起作用。这个问题有 tidyverse
解决方案吗?
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
列(这是数字)。执行 arrange
也使事情变得更加灵活,即假设我们只想基于子字符串(即数字部分)进行排序,可以提取这些并执行排序,而在 names_sort
中可能并非如此
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)
我正在跟进
我被建议 tidyverse
解决方案吗?
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
列(这是数字)。执行 arrange
也使事情变得更加灵活,即假设我们只想基于子字符串(即数字部分)进行排序,可以提取这些并执行排序,而在 names_sort
中可能并非如此
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)