【问题标题】:Summarize Rows with总结行
【发布时间】:2021-09-15 14:44:30
【问题描述】:

我正在尝试从我们的商店订单工具中减少和简化数据集。 我们的工具将每个订单行导出为具有重复值的新订单。 比如当前的导出是这样的:

  ORDER PRODUCT STORE OPTIONAL PRICE
  <chr> <chr>   <chr> <chr>    <dbl>
1 ord1  p1      s1    Y            3
2 ord2  p2      s2    N            2
3 ord3  p3      s3    Y            3
4 ord3  p2      s3    N            5
5 ord3  p2      s3    Y            6
6 ord4  p3      s2    Y            1

示例代码如下:

data <- tibble("ORDER"=c("ord1","ord2","ord3","ord3","ord3","ord4"),"PRODUCT"=c("p1","p2","p3","p2","p2","p3"),STORE=c("s1","s2","s3","s3","s3","s2"),"OPTIONAL"=c("Y","N","Y","N","Y","Y"),"PRICE"=c(3,2,3,5,6,1))

我的目标是创建一个数据集:

  • 每个订单中为特定产品支付的总金额(我们有 220 种不同的产品)
  • 如果客户要求或不要求一个可选的

我已经设法通过以下方式旋转表格:

    > data_wide <- data %>% 
+     pivot_wider(names_from = PRODUCT, values_from = PRICE, values_fill = NA ,
+                 values_fn = list(PRICE = sum))

现在我有了这个小标题:

  ORDER STORE OPTIONAL    p1    p2    p3
  <chr> <chr> <chr>    <dbl> <dbl> <dbl>
1 ord1  s1    Y            3    NA    NA
2 ord2  s2    N           NA     2    NA
3 ord3  s3    Y           NA     6     3
4 ord3  s3    N           NA     5    NA
5 ord4  s2    Y           NA    NA     1

我想创建一个类似的表:

  ORDER STORE OPTIONAL    p1    p2    p3
  <chr> <chr> <chr>    <dbl> <dbl> <dbl>
1 ord1  s1    Y            3    NA    NA
2 ord2  s2    N           NA     2    NA
3 ord3  s3    Y           NA    11     3
4 ord4  s2    Y           NA    NA    NA

对于每种产品,我在哪里获得了支付的总价,并且我知道客户是否要求提供可选产品(我不关心哪种产品)。 我不知道该如何面对:

  • 我不会丢失有关单次购买的信息(例如商店)
  • 我需要一个唯一的 ORDER id,因为我将加入客户信息数据集

谢谢!

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    解决方案选项

    library(tidyverse)
    data <-
      tibble(
        "ORDER" = c("ord1", "ord2", "ord3", "ord3", "ord3", "ord4"),
        "PRODUCT" = c("p1", "p2", "p3", "p2", "p2", "p3"),
        STORE = c("s1", "s2", "s3", "s3", "s3", "s2"),
        "OPTIONAL" = c("Y", "N", "Y", "N", "Y", "Y"),
        "PRICE" = c(3, 2, 3, 5, 6, 1)
      )
    
    data %>%
      pivot_wider(
        names_from = PRODUCT,
        values_from = c(PRICE),
        values_fill = NA ,
        values_fn = list(PRICE = sum)
      ) %>% 
      group_by(ORDER, STORE) %>% 
      summarise(
        OPTIONAL = if_else(sum(OPTIONAL == "Y") > 0, "Y", "N"),
        across(starts_with("p"), ~sum(.x)), .groups = "drop"
        )
    #> # A tibble: 4 x 6
    #>   ORDER STORE OPTIONAL    p1    p2    p3
    #>   <chr> <chr> <chr>    <dbl> <dbl> <dbl>
    #> 1 ord1  s1    Y            3    NA    NA
    #> 2 ord2  s2    N           NA     2    NA
    #> 3 ord3  s3    Y           NA    11    NA
    #> 4 ord4  s2    Y           NA    NA     1
    

    reprex package (v2.0.0) 于 2021-07-04 创建

    【讨论】:

      【解决方案2】:

      您可以使用dplyrtidyr

      library(dplyr)
      library(tiydr)
      
      data %>% 
        pivot_wider(names_from="PRODUCT", values_from="PRICE", values_fill=0) %>% 
        mutate(OPTIONAL = OPTIONAL == "Y") %>% 
        group_by(ORDER, STORE) %>% 
        summarise(across(c("OPTIONAL", matches("p\\d+")), ~ sum(.x)), .groups="drop") %>% 
        mutate(OPTIONAL = ifelse(OPTIONAL > 0, "Y", "N"),
               across(matches("p\\d+"), ~na_if(.x,0))) 
      

      返回

      # A tibble: 4 x 6
        ORDER STORE OPTIONAL    p1    p2    p3
        <chr> <chr> <chr>    <dbl> <dbl> <dbl>
      1 ord1  s1    Y            3    NA    NA
      2 ord2  s2    N           NA     2    NA
      3 ord3  s3    Y           NA    11     3
      4 ord4  s2    Y           NA    NA     1
      

      【讨论】:

        猜你喜欢
        • 2012-12-28
        • 2013-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-09
        • 2019-12-20
        • 1970-01-01
        相关资源
        最近更新 更多