【问题标题】:combine tidyr::spread and dplyr::summarise in single step一步结合 tidyr::spread 和 dplyr::summarise
【发布时间】:2018-07-27 21:45:06
【问题描述】:

我经常想在“单步”中执行tidyr::spreaddplyr::summarise 以按组聚合数据。我想要的显示在expected 中。我可以通过分别执行summarisespread 并将结果与​​dplyr::full_join 组合来获得expected,但我正在寻找避免full_join 的替代方法。不需要真正的单步方法。

df <- data.frame(
        id = rep(letters[1], 2),
        val1 = c(10, 20),
        val2 = c(100, 200),
        key = c("A", "B"),
        value = c(1, 2))

library(tidyverse)
result1 <- df %>%
              group_by(id) %>%
              summarise(
                val1 = min(val1),
                val2 = max(val2)
              )
# A tibble: 1 x 3
  # id      val1  val2
  # <fctr> <dbl> <dbl>
# 1 a       10.0   200

result2 <- df %>%
              select(id, key, value) %>%
              group_by(id) %>%
              spread(key, value)
# A tibble: 1 x 3
# Groups: id [1]
  # id         A     B
# * <fctr> <dbl> <dbl>
# 1 a       1.00  2.00

expected <- full_join(result1, result2, by="id")
# A tibble: 1 x 5
  # id      val1  val2     A     B
  # <fctr> <dbl> <dbl> <dbl> <dbl>
# 1 a       10.0   200  1.00  2.00

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    使用do的另一种方法:

    res <- df %>%
      group_by(id) %>%
      summarise(
        val1 = min(val1),
        val2 = max(val2),
        key = list(key),
        value = list(value)
      ) %>% group_by(id, val1, val2) %>%
      do( matrix(.$value[[1]], nrow=1) %>% as.data.frame %>% setNames(as.character(.$key[[1]])) )
    

    【讨论】:

      【解决方案2】:

      自我回答:这是一种适用于 tidyr::nest 的方法,但它看起来“杂乱无章”,也好不到哪里去

      df %>%
        group_by(id) %>%
        nest() %>%
        mutate(
          min_vals = map(data, ~.x %>% summarise(min_val = min(val1), max_val = max(val2))),
          data = map(data, ~select(.x, key, value) %>% spread(key, value))
        ) %>%
        unnest()
      
      # A tibble: 1 x 5
        # id         A     B min_val max_val
        # <fctr> <dbl> <dbl>   <dbl>   <dbl>
      # 1 a       1.00  2.00    10.0     200
      

      【讨论】:

        【解决方案3】:

        我怀疑您的数据可能有更多需要修改的边缘情况,但您为什么不简单地spread 然后summarise?您可以为每个变量单独指定汇总函数,因此对于您实际上不需要计算任何东西的AB(我假设)您可以删除所有NA

        df %>%
          spread("key", "value") %>%
          group_by(id) %>%
          summarise(
            val1 = min(val1),
            val2 = max(val2),
            A = mean(A, na.rm = TRUE),
            B = mean(B, na.rm = TRUE)
            )
        # A tibble: 1 x 5
          id     val1  val2     A     B
          <fct> <dbl> <dbl> <dbl> <dbl>
        1 a      10.0   200  1.00  2.00
        

        【讨论】:

        • 这可能是最简单的方法。在接受之前,我会看看在接下来的几天内是否会弹出其他答案。
        猜你喜欢
        • 2015-06-05
        • 2022-11-23
        • 2016-05-24
        • 1970-01-01
        • 2019-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-27
        相关资源
        最近更新 更多