【问题标题】:DRY-ing a common R code pattern干燥一个常见的 R 代码模式
【发布时间】:2015-07-14 05:59:48
【问题描述】:

我在一些 r 代码中得到了我想象中相当常见的模式。我有一个带有数字向量的数据框,我想根据数字向量的特定值创建另一个因子变量。

目前这是我的代码的样子:

add_category <- function(sample) {
   sample$category <- NA
   sample$category[sample$numeric_vars < 25000] <- '1. Below 25k'
   sample$category[sample$numeric_vars >= 25000] <- '2. Above 25k'
   sample$category[sample$numeric_vars >= 50000] <- '3. Above 50k'
   sample$category <- as.factor(sample$category)
   return(sample)
}

我遇到的问题是这段代码有很多重复,我不能轻易测试它。我一直在努力想办法减少重复,但我已经用头撞了几个小时,但没有取得多大成功。

所以我的问题是,如何在基础 R 中以 DRY 方式复制这种模式?

编辑:

所以为了让这个更清楚一点,我知道我可以使用cut 来解决这个特殊问题。我对解决这类问题的策略更感兴趣,即根据对另一个变量的特定实例的一些测试来重新编码一个单独的变量。

在 Hadley 的高级 R 函数编程部分中,他使用了将 -99 重新编码为 NA 的示例。这是类似的,但对于一列上的各种值。

【问题讨论】:

  • 您可以使用cut 减少代码行数。即cut(sample$numeric_vars, breaks=c(-Inf, 25000, 50000,Inf), labels=yourlabels) 示例数据会有所帮助
  • @Khashaa 是的,那一章很有用,但其中 Hadley 正在讨论在各种列中应用类似的操作,这是在具有各种值的一列上。
  • 另一个选项是factor(1+ 2*(v1 &lt; 25000) + 4*(v1 &gt;= 25000) + 8*(v1 &gt;= 50000), labels=c('1. Below 25k', '2. Above 25k', '3. Above 50k')),其中v1是值的向量。
  • 如果你问的是一般原则,我会说你的问题有点过于宽泛,我认为 Hadley 在他的书中雄辩地解决了这个问题。

标签: r


【解决方案1】:

我可以剃掉几条线。否则看起来很好。

add_category <- function(sample) {
    sample$category <- '1. Below 25k'
    sample$category[sample$numeric_vars >= 25000] <- '2. Above 25k'
    sample$category[sample$numeric_vars >= 50000] <- '3. Above 50k'
    return(sample)
}

应该已经是因素了。

【讨论】:

    【解决方案2】:

    只有几个级别,在这种情况下,手动完成仍然是合理的。

    df <- data.frame(numeric.var = runif(100000,0,75000))
    add_Cat <- function(var) {
      as.factor(ifelse(var > 50000, "3. Above 50k",
        ifelse(var > 25000, "2. Above 25k", "1. Below 25k'")))
    }
    

    如果您有兴趣,我有一个更通用的解决方案,但它会破坏 KISS 以使其干燥。

    实际上我收回了这个答案,并且在运行以下基准测试后需要在其他地方重新考虑我的代码:

    microbenchmark(add_Cat(df), add_category(df))
    Unit: microseconds
                expr       min         lq       mean    median         uq        max neval
         add_Cat(df) 69179.970 70801.9170 72700.5511 71881.748 72627.1110 144267.491   100
    add_category(df)   690.199   728.6855   894.3915   778.535   803.2765   2717.907   100
    

    【讨论】:

    • 好,我们来看看复杂的版本!
    猜你喜欢
    • 2014-12-13
    • 1970-01-01
    • 2014-08-03
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多