【问题标题】:How to optimize case_when in a function?如何在函数中优化 case_when?
【发布时间】:2020-07-08 17:20:52
【问题描述】:

我想编写一个函数,根据一些原始数据创建一个分箱变量。具体来说,我有一个包含每个受访者年龄值的日期集,我想编写一个函数将该人分类到一个年龄组,其中年龄组是该函数的一个参数。

这是我开始的:

data <- data.frame(age = 18:100)

foo <- function(data, brackets = list(18:24, 25:34, 35:59)) {
  require(tidyverse)
  tmp <- data %>%
    drop_na(age) %>%
    mutate(age_bracket = case_when(age %in% brackets[[1]] ~ paste(brackets[[1]][1], "to", brackets[[1]][length(brackets[[1]])]),
                                   age %in% brackets[[2]] ~ paste(brackets[[2]][1], "to", brackets[[2]][length(brackets[[2]])]),
                                   age %in% brackets[[3]] ~ paste(brackets[[3]][1], "to", brackets[[3]][length(brackets[[3]])])))
print(tmp)
}

很明显,case_when 部分非常不灵活,因为我必须提前指定括号的数量。它也相当冗长。我想编写某种循环来查看括号参数中的元素数量并相应地创建这些括号。所以如果我想添加一个 60:Inf 年龄组,该函数应该添加另一个年龄组。

在网上搜索后,发现someuse解散了表达式(例如quos)。我对这些很陌生,所以我很难将它们用于我的目的。

【问题讨论】:

  • 使用cut并控制它的labels=会更好吗?
  • 顺便说一句,你可能不想尝试做age %in% 60:Inf ...
  • 虽然标签本身可以稍作调整,但我怀疑 cut(data$age, c(0, 18, 25, 35, 60, Inf), include.lowest = TRUE) 给了你很多这似乎在做的事情。
  • 顺便说一句:您使用require(tidyrverse) 是不明智的。如果所有tidyverse 都不可用,则该功能将继续有增无减(因为require 不会stop 出错),但如果dplyrtidyr 失败,它可能会在下一行失败。建议:(1)只需要你需要的包,这里dplyrtidyr; (2a) 之一使用 library,这样如果加载失败,就会出现有意义的错误消息,或者 (2b) 使用 if (!require(...)) { fail_action },这样您就可以真正使用 require 是什么用于。参考:stackoverflow.com/a/51263513/3358272
  • paste(v[-length(v)], v[-1]-1, sep = " to ")

标签: r function dplyr tidyverse nse


【解决方案1】:

我认为您正在寻找cut 函数。以下是这项工作:

data <- data.frame(age = 18:100)

data$age_bracket <- cut(data$age, breaks = c(0, 18, 25, 35, 60, Inf))

unique(data$age_bracket)
# [1] (0,18]   (18,25]  (25,35]  (35,60]  (60,Inf]
# Levels: (0,18] (18,25] (25,35] (35,60] (60,Inf]

如果您不链接括号默认标签,您也可以定义labels。使用cut 而不是手动编码的解决方案的优点是您可以使用cut 的输出进行常规操作(例如排序)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 2021-09-05
    • 2019-04-06
    • 2020-07-17
    相关资源
    最近更新 更多