如何在 R 中使用 bang bangs (!!) 和 fancycut?

How to use bang bangs (!!) with fancycut in R?

我正在尝试使用 fancycut 使用一些预定义的间隔来剪切数据。我想以编程方式执行此操作,即我不想去复制过去

fancycut(age, 0-4 = '[0,4]'....

这是一个 MWE 向您展示我的意思:

age <- c(19, 41,6, 82, 29, 39, 84, 34, 97, 22)

fancy_labels <- c("00-04", "05-09", "10-14", "15-19", 
                  "20-24", "25-29", "30-34", "35-39", 
                  "40-44", "45-49", "50-54", "55-59", 
                  "60-64", "65-69", "70+")

fancy_range <- c("[0, 4]","[5, 9]","[10, 14]","[15, 19]",
                 "[20, 24]","[25, 29]","[30, 34]","[35, 39]",
                 "[40, 44]","[45, 49]","[50, 54]","[55, 59]",
                 "[60, 64]","[65, 69]","[70, Inf]")

我只想插入 fancy_range 的值和 fancy_labels 的标签。我认为这应该可以使用 bang bang 运算符,但我正在努力使其工作。

这个

fancycut(age, !!fancy_labels = !!fancy_range)

不适合我。

double-bang 运算符不是 R 的原生运算符,而是一种用于在 tidyverse 中选择性取消引用的特殊结构。您不能在此上下文中使用它。

要创建一个调用而无需在 base R 中输入所有内容,您必须构建一个配对列表并将其转换为一个调用,然后对其进行评估(这是 !! 运算符在以下情况下在幕后有效执行的操作在正确的上下文中使用)

类似于:

eval(as.call(c(fancycut, x = quote(age), 
               setNames(as.list(fancy_range), fancy_labels))))
#> [1] 15-19 40-44 05-09 70+   25-29 35-39 70+   30-34 70+   20-24
#> 15 Levels: 00-04 05-09 10-14 15-19 20-24 25-29 30-34 35-39 40-44 45-49 ... 70+

但是,您需要先修正您的输入。在 age 向量之前没有 c,并且您的范围需要用大括号或直括号括起来:

age <- c(19, 41,6, 82, 29, 39, 84, 34, 97, 22)

fancy_labels <- c("00-04", "05-09", "10-14", "15-19", "20-24", 
                  "25-29", "30-34", "35-39", "40-44", "45-49", 
                  "50-54", "55-59", "60-64", "65-69", "70+")

fancy_range <- c("[0, 4]","(5, 9]","(10, 14]","(15, 19]",
                 "(20, 24]","(25, 29]","(30, 34]","[35, 39]",
                 "[40, 44]","[45, 49]","[50, 54]","[55, 59]",
                 "[60, 64]","[65, 69]","[70, Inf]")

fancycutwafflecut 的包装器。

fancycut
function (x, na.bucket = NA, unmatched.bucket = NA, out.as.factor = TRUE, 
    ...) 
{
    dots <- as.list(substitute(list(...)))[-1L]
    if (length(dots) > 0) {
        buckets <- names(dots)
        intervals <- as.character(dots)
    }
    return(wafflecut(x = x, intervals = intervals, buckets = buckets, 
        na.bucket = na.bucket, unmatched.bucket = unmatched.bucket, 
        out.as.factor = out.as.factor))
}

除了调用 wafflecut 之外,函数中没有进行任何操作。所以,我们可以直接调用wafflecut

wafflecut(age, intervals = fancy_range, buckets = fancy_labels)
#[1] 15-19 40-44 05-09 70+   25-29 35-39 70+   30-34 70+   20-24
#Levels: 00-04 05-09 10-14 15-19 20-24 25-29 30-34 35-39 40-44 45-49 50-54 55-59 60-64 65-69 70+

我想你想要 unquote-splice 运算符 !!! 在这里:

rlang::exec( fancycut, age, !!!setNames(fancy_range, fancy_labels) )
#  [1] 15-19 40-44 05-09 70+   25-29 35-39 70+   30-34 70+   20-24
# 15 Levels: 00-04 05-09 10-14 15-19 20-24 25-29 30-34 35-39 40-44 ... 70+