【问题标题】:Split data into lists and operate within each list using tidyverse将数据拆分为列表并使用 tidyverse 在每个列表中进行操作
【发布时间】:2021-06-22 22:17:33
【问题描述】:

以下是我的数据:

structure(list(region = c("global", "global", "global", "africa", 
"africa", "africa", "asia", "asia", "asia"), disease = c("hear", 
"lung", "ear", "hear", "lung", "ear", "hear", "lung", "ear"), 
    number = c(20L, 22L, 40L, 14L, 12L, 16L, 15L, 18L, 10L)), class = "data.frame", row.names = c(NA, 
-9L))

我希望获得每个区域内肺部疾病数量的排名。我想要的结果应该是一个向量 c(2, 3, 1),因为肺病的数量在全球三大疾病中排名全球第二,在非洲在三大疾病中排名第三,在亚洲在三大疾病中排名第一。

我使用group_split 创建单独的列表,但我未能在每个列表中进行进一步计算。我尝试了map 功能,但它不起作用。因此我想问一下,如果我想在 tidyverse 生态系统中操作,我应该怎么做才能获得预期的结果?

谢谢。

【问题讨论】:

    标签: r dplyr purrr


    【解决方案1】:

    如果您想像以前的数据一样返回完整的数据,有两种选择。

    option-1 使用purrr::map_dfr

    map_dfr((df %>% group_split(region)), ~ (as.data.frame(.) %>% mutate(rank = dense_rank(number))))
    
      region disease number rank
    1 africa    hear     14    2
    2 africa    lung     12    1
    3 africa     ear     16    3
    4   asia    hear     15    2
    5   asia    lung     18    3
    6   asia     ear     10    1
    7 global    hear     20    1
    8 global    lung     22    2
    9 global     ear     40    3
    

    选项 2 仅使用 dplyr

    df %>% group_by(region) %>% mutate(rank = dense_rank(number))
    # A tibble: 9 x 4
    # Groups:   region [3]
      region disease number  rank
      <chr>  <chr>    <int> <int>
    1 global hear        20     1
    2 global lung        22     2
    3 global ear         40     3
    4 africa hear        14     2
    5 africa lung        12     1
    6 africa ear         16     3
    7 asia   hear        15     2
    8 asia   lung        18     3
    9 asia   ear         10     1
    

    现在您可以轻松过滤掉输出向量。

    (df %>% group_by(region) %>% mutate(rank = dense_rank(number)))[which(df$disease == "lung"), "rank"]
    # A tibble: 3 x 1
       rank
      <int>
    1     2
    2     1
    3     3
    

    如果您想将mapgroup_split 一起使用,请这样做

    map_dfr((df %>% group_split(region)), ~ (as.data.frame(.) %>% mutate(rank = dense_rank(number)) %>% filter(disease == "lung") %>%
                                           select(region, rank)))
    
      region rank
    1 africa    1
    2   asia    3
    3 global    2
    

    【讨论】:

    • 为什么不直接做:df %&gt;% group_by(region) %&gt;% mutate(rank = dense_rank(number)) %&gt;% filter(disease == 'lung') %&gt;% select(rank)
    • @JustinCocco 我的回答中的第二个选项正是这个。但我认为 OP 希望通过 map 系列函数实现它,这就是发布详细解决方案的原因。
    • 不,我的意思是您使用 [which(df[,’disease’]==“lung”, ‘rank’] 而不是 filter() %&gt;% select(),我只是好奇是否有原因。
    猜你喜欢
    • 1970-01-01
    • 2018-06-02
    • 2018-01-21
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    相关资源
    最近更新 更多