【问题标题】:dplyr & tibble - conditional sum of two rows based on column valuedplyr & tibble - 基于列值的两行的条件总和
【发布时间】:2021-11-19 02:16:17
【问题描述】:

鉴于如下所示的 tibble,我正在尝试使用 Tidyverse 根据两个字段中的 Item 的值执行条件求和。具体来说,对于foo 和bar,我想将与项目a 对应的值与项目b 的值相加,然后删除前者的行。我正在寻找的结果如表 2 所示。

data <- tibble(Field = rep(c("foo", "bar"), each=4),
               Item = rep(c("a", "b", "c", "d"), 2),
               Value = runif(8))
# table 1                          # table 2
| Field | Item |   Value   |       | Field | Item |   Value   |
|-------|------|-----------|       |-------|------|-----------|
|  foo  |  a   | 0.8167347 |       |  foo  |  b   | 0.9583989 | <== 0.8167347 + 0.1416642
|  foo  |  b   | 0.1416642 |       |  foo  |  c   | 0.7054814 |
|  foo  |  c   | 0.7054814 |       |  foo  |  d   | 0.1196948 |
|  foo  |  d   | 0.1196948 |       |--------------------------|
|--------------------------|       |  bar  |  b   | 0.6177568 | <== 0.3604500 + 0.2573068
|  bar  |  a   | 0.3604500 |       |  bar  |  c   | 0.7003040 |
|  bar  |  b   | 0.2573068 |       |  bar  |  d   | 0.8131556 |
|  bar  |  c   | 0.7003040 |
|  bar  |  d   | 0.8131556 |

到目前为止,我还没有达到预期的结果。我知道如何使用dplyr 的分组功能来隔离属于这两个字段之一的项目,但我不知道如何选择a 的值并在分组完成后将其与b 相加执行。

【问题讨论】:

    标签: r dataframe dplyr tidyverse tibble


    【解决方案1】:

    你可以改变Item,当它等于a时接收b,然后总结

    library(dplyr)
    

    数据

    set.seed(123)
    data <- tibble(Field = rep(c("foo", "bar"), each=4),
                   Item = rep(c("a", "b", "c", "d"), 2),
                   Value = runif(8))
    
    # A tibble: 8 x 3
    Field Item   Value
    <chr> <chr>  <dbl>
    1 foo   a     0.288 
    2 foo   b     0.788 
    3 foo   c     0.409 
    4 foo   d     0.883 
    5 bar   a     0.940 
    6 bar   b     0.0456
    7 bar   c     0.528 
    8 bar   d     0.892
    

    结果

    data %>% 
      mutate(Item = if_else(Item == "a","b",Item)) %>% 
      group_by(Field,Item) %>% 
      summarise(Value = sum(Value,na.rm = TRUE)) %>% 
      ungroup()
    
    # A tibble: 6 x 3
    Field Item  Value
    <chr> <chr> <dbl>
    1 bar   b     0.986
    2 bar   c     0.528
    3 bar   d     0.892
    4 foo   b     1.08 
    5 foo   c     0.409
    6 foo   d     0.883
    

    【讨论】:

      【解决方案2】:

      使用case_when将'Item'列中的'a'替换为'b',同时使用'Field'和'item'作为分组列,并在summarise中获取“Value”的sum

      library(dplyr)
      data %>%
          group_by(Field, Item = case_when(Item == 'a' ~ 'b', TRUE ~ Item)) %>% 
          summarise(Value = sum(Value, na.rm = TRUE), .groups= 'drop')
      

      -输出

      # A tibble: 6 × 3
        Field Item  Value
        <chr> <chr> <dbl>
      1 bar   b     0.618
      2 bar   c     0.700
      3 bar   d     0.813
      4 foo   b     0.958
      5 foo   c     0.705
      6 foo   d     0.120
      

      数据

      data <- structure(list(Field = c("foo", "foo", "foo", "foo", "bar", "bar", 
      "bar", "bar"), Item = c("a", "b", "c", "d", "a", "b", "c", "d"
      ), Value = c(0.8167347, 0.1416642, 0.7054814, 0.1196948, 0.36045, 
      0.2573068, 0.700304, 0.8131556)), row.names = c(NA, -8L), class = c("tbl_df", 
      "tbl", "data.frame"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-10-24
        • 2016-03-22
        • 2021-03-01
        • 2022-12-15
        • 1970-01-01
        • 1970-01-01
        • 2016-10-04
        相关资源
        最近更新 更多