【问题标题】:R create summary percentages in a dataframe using cells that will become different denominatorsR 使用将成为不同分母的单元格在数据框中创建汇总百分比
【发布时间】:2021-08-01 15:50:23
【问题描述】:

这是我的数据框。它不是很长 - 只有六行。

df <- structure(list(Send_Month = c("2021-05", "2021-06", "2021-07", 
"2021-05", "2021-06", "2021-07"), Order_Result = c("No", "No", 
"No", "Yes", "Yes", "Yes"), Email_Send = c(135, 495, 475, 7, 
28, 25), Unique_Email_Opens = c(45, 149, 143, 7, 28, 25), Unique_Email_Clicks = c(6, 
21, 10, 7, 28, 25), Total_Orders = c(37, 106, 46, 7, 28, 25)), row.names = c(NA, 
-6L), groups = structure(list(Send_Month = c("2021-05", "2021-06", 
"2021-07"), .rows = structure(list(c(1L, 4L), c(2L, 5L), c(3L, 
6L)), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", 
"list"))), row.names = c(NA, -3L), class = c("tbl_df", "tbl", 
"data.frame"), .drop = TRUE), class = c("grouped_df", "tbl_df", 
"tbl", "data.frame"))

我无法想象如何获得可以绘制成条形图的摘要结果。我正在尝试在这里进行一些分组:

当月份相同(例如,“2021-05”)并且我查看 Email_Send 变量时,我可以看到发送的 142 封电子邮件中有 7 封(即 135+7)导致了订单.我还可以看到打开的 52 封电子邮件(即 45+7)中有 7 封导致了订单。在被点击的 13 封电子邮件中,有 7 封(即 6+7)导致了订单。那是给“2021-05”组的。

如何为每个分组创建这些统计信息,以便查看每个组的百分比将如何变化,分母在哪里不断变化?

我尝试使用 janitor 包一秒钟,只是为了确定自己的方向,我首先过滤为仅包含 2021-05 组:

df_may <- df %>%
  filter(Send_Month == "2021-05")

df_may %>%
  adorn_totals("row")

但我不知道这种方法对于同时查看所有组是否非常灵活,而且我不知道我是否真的想要一个摘要行或一个新列。所以我不知道我是否朝着正确的方向前进。

【问题讨论】:

    标签: r dataframe summary


    【解决方案1】:

    感谢亲爱的@ThomasIsCoding 提供使用proporstions 函数代替.x/sum(.x) 的绝妙技巧。

    library(dplyr)
    library(purrr)
    
    df %>%
      group_by(Send_Month, .add = TRUE) %>%
      group_split() %>%
      map(~ .x %>% 
            mutate(across(!c(1, 2), ~ proportions(.x))))
    
    [[1]]
    # A tibble: 2 x 6
      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks Total_Orders
      <chr>      <chr>             <dbl>              <dbl>               <dbl>        <dbl>
    1 2021-05    No               0.951               0.865               0.462        0.841
    2 2021-05    Yes              0.0493              0.135               0.538        0.159
    
    [[2]]
    # A tibble: 2 x 6
      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks Total_Orders
      <chr>      <chr>             <dbl>              <dbl>               <dbl>        <dbl>
    1 2021-06    No               0.946               0.842               0.429        0.791
    2 2021-06    Yes              0.0535              0.158               0.571        0.209
    
    [[3]]
    # A tibble: 2 x 6
      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks Total_Orders
      <chr>      <chr>             <dbl>              <dbl>               <dbl>        <dbl>
    1 2021-07    No                 0.95              0.851               0.286        0.648
    2 2021-07    Yes                0.05              0.149               0.714        0.352
    

    【讨论】:

    • 太棒了!我学会了如何使用dplyr 来回答你的这个问题:) 顺便说一句,你可以试试~ proportions(.x)
    • 非常感谢。我刚刚添加了你的精彩建议。不知道。哦,我的荣幸,我们也从你那里学到了很多东西。在这里,我通常会使用单个group_split,但它会首先向group_by 发出警告,然后是group_split。这很奇怪,但结果是一样的。
    • 这里有很棒的建议! .add = TRUE 有什么作用?我将其更改为 .add = FALSE 只是为了测试,我想我得到了相同的结果
    • 哈哈,相互学习!我猜mutate(across(!c(1, 2), proportions)) 会更短
    • @hachiko 不客气。其实这里没什么。如果您已经按另一个变量分组 .add = TRUE 将向它添加另一个分组变量而不是覆盖它。在这里,我首先使用了group_split,它发出了一个警告,首先使用group_by,然后group_split,但它是建议的语法,并且会产生相同的结果。
    【解决方案2】:

    更新

    如果不想有列表格式的输出,可以试试

    df %>%
      group_by(Send_Month) %>%
      mutate(across(Email_Send:Total_Orders, proportions)) %>%
      ungroup()
    

    给了

      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks
      <chr>      <chr>             <dbl>              <dbl>               <dbl>
    1 2021-05    No               0.951               0.865               0.462
    2 2021-06    No               0.946               0.842               0.429
    3 2021-07    No               0.95                0.851               0.286
    4 2021-05    Yes              0.0493              0.135               0.538
    5 2021-06    Yes              0.0535              0.158               0.571
    6 2021-07    Yes              0.05                0.149               0.714
    # ... with 1 more variable: Total_Orders <dbl>
    

    也许你可以试试下面的代码

    > lapply(split(df, df$Send_Month), function(x) {x[-(1:2)]<-proportions(as.matrix(x[-(1:2)]), 2);x})
    $`2021-05`
    # A tibble: 2 x 6
    # Groups:   Send_Month [1]
      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks
      <chr>      <chr>             <dbl>              <dbl>               <dbl>
    1 2021-05    No               0.951               0.865               0.462
    2 2021-05    Yes              0.0493              0.135               0.538
    # ... with 1 more variable: Total_Orders <dbl>
    
    $`2021-06`
    # A tibble: 2 x 6
    # Groups:   Send_Month [1]
      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks
      <chr>      <chr>             <dbl>              <dbl>               <dbl>
    1 2021-06    No               0.946               0.842               0.429
    2 2021-06    Yes              0.0535              0.158               0.571
    # ... with 1 more variable: Total_Orders <dbl>
    
    $`2021-07`
    # A tibble: 2 x 6
    # Groups:   Send_Month [1]
      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks
      <chr>      <chr>             <dbl>              <dbl>               <dbl>
    1 2021-07    No                 0.95              0.851               0.286
    2 2021-07    Yes                0.05              0.149               0.714
    # ... with 1 more variable: Total_Orders <dbl>
    

    【讨论】:

    • 非常感谢您提供此内容。我赞成你的,但我检查了另一个答案只是因为我更了解 dplyr 代码。我认为它们都是很好的答案。你做这件事的速度给我留下了深刻的印象
    • 有没有办法将所有这些重新组合到一个数据框中,而不是使用一个列表?我想取这三个部分,然后是 bind_rows(),这样我就可以有一个汇总表 - 这可能吗?
    • @hachiko 查看我的更新。希望这是你想要的。
    • 太棒了,这正是我所希望的,给我留下了深刻的印象
    【解决方案3】:

    使用看门人,假设您想从百分比计算中免除列 Total_Orders

    library(janitor)
    library(tidyverse)
    
    split(df, df$Send_Month) %>%
      map_df(adorn_percentages, "col", TRUE, -c(1, 2, Total_Orders))
    
    # A tibble: 6 x 6
    # Groups:   Send_Month [3]
      Send_Month Order_Result Email_Send Unique_Email_Opens Unique_Email_Clicks Total_Orders
      <chr>      <chr>             <dbl>              <dbl>               <dbl>        <dbl>
    1 2021-05    No               0.951               0.865               0.462           37
    2 2021-05    Yes              0.0493              0.135               0.538            7
    3 2021-06    No               0.946               0.842               0.429          106
    4 2021-06    Yes              0.0535              0.158               0.571           28
    5 2021-07    No               0.95                0.851               0.286           46
    6 2021-07    Yes              0.05                0.149               0.714           25
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-23
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多