【问题标题】:convert SQL summation and calc to dplyr in R在 R 中将 SQL 求和和计算转换为 dplyr
【发布时间】:2020-10-01 17:50:04
【问题描述】:

作为 SQL 查询的一部分,作为聚合的一部分,我想将其转换为 dplyr 语法:

case when sum(amy_jan) != 0 then sum(cost_jan)/sum(amy_jan) else 0 end  as ratio_jan
-- ...
case when sum(amy_dec) != 0 then sum(cost_dec)/sum(amy_dec) else 0 end  as ratio_dec

在 dplyr 语法中会是什么样子?

【问题讨论】:

  • billrowe,您之前的 8 个问题中有 7 个有答案,但其中没有一个包含您的评论,即答案没有解决您的问题。请返回accept them。虽然选择不接受答案当然是您的权利,但这违反了 Stack 网站上的礼仪和礼貌。谢谢。
  • 您不能只将其转换为 dplyr。 SQL 不执行为。是。数据库从非常不同的查询创建执行计划,可能决定缓存中间结果,确保总和只计算一次等。您必须考虑如何以有效的方式进行计算并避免例如计算sum(amy_dec) 多次超过1M 行。您不太可能比拥有数十个内核和 GB 内存的数据库服务器更快地执行这些计算
  • 谢谢。欣赏洞察力。

标签: r dplyr case


【解决方案1】:

如果您要查找的只是与您的 SQL-case ... when ... 语句等效的 dplyr,则它是 dplyr::case_when()
更具体地说,在您似乎正在描述的用例 (giving a reproducible example of any kind and your expected output would've been helpful here!) 上,类似这样的内容将展示此功能:

library(dplyr)
library(purrr)

months <- tolower(month.abb)

# here I'm dummying some data, like what you're describing
df <- months %>%
  map_dfc(
    ~ tibble(
      !!paste0("cost_", .x) := sample(0:10, 100, replace = T),
      !!paste0("amy_", .x) := sample(0:10, 100, replace = T)
    )
  )

# summarise that dataframe, once for every month in our list
df_summary <- df %>%
  summarise(
    ratio_jan = case_when(
      sum(amy_jan) > 0 ~ sum(cost_jan) / sum(amy_jan),
      T ~ 0
    ),
    # ratio_feb = case_when(...),
    # ... and so on, for every month
  )

以上内容包含case_when 以在dplyr 中重现您以SQL 风格共享的内容。

下面的代码是一个扩展,使用purrr::map_dfc 来迭代缩短的月份并绑定计算的“ratio_xxx”值。这样就省去了对 12 个变量计算进行硬编码的麻烦... :)

df_summary2 <- months %>%
  map_dfc(
    ~ df %>%
      summarise(
        !!paste0("ratio_", .x) := case_when(
          sum(.data[[paste0("amy_", .x)]]) > 0 ~ sum(.data[[paste0("cost_", .x)]]) / sum(.data[[paste0("amy_", .x)]]),
          T ~ 0
        )
      )
  )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多