R中括号后面跟着括号是什么意思

its*_*ami 6 r

scales::label_percent()在 mutate 函数中使用的语法很不寻常,因为它使用双括号:

\n

label_percent()(an_equation_goes_here)

\n

我认为我以前没有见过()()R 中的语法,而且我不知道如何查找它,因为我不知道它叫什么。我尝试过?`()()`??`()()`但都没有帮助。双括号语法称为什么?有人可以推荐一个阅读相关内容的地方吗?

\n

这是上下文的示例:

\n
library(tidyverse)\nmembers <- \n  read_csv(\n    paste0(\n      "https://raw.githubusercontent.com/rfordatascience/tidytuesday/", \n      "master/data/2020/2020-09-22/members.csv"\n    ), \n    show_col_types = FALSE)\n\n\nmembers %>%\n  count(success, died) %>%\n  group_by(success) %>%\n  # old syntax:\n  # mutate(percent = scales::percent(n / sum(n))) \n  # new syntax:\n  mutate(percent = scales::label_percent()(n / sum(n))) \n#> # A tibble: 4 \xc3\x97 4\n#> # Groups:   success [2]\n#>   success died      n percent\n#>   <lgl>   <lgl> <int> <chr>  \n#> 1 FALSE   FALSE 46452 98%    \n#> 2 FALSE   TRUE    868 2%     \n#> 3 TRUE    FALSE 28961 99%    \n#> 4 TRUE    TRUE    238 1%\n
Run Code Online (Sandbox Code Playgroud)\n

创建于 2023-01-01,使用reprex v2.0.2

\n

r2e*_*ans 10

大多数函数都会返回一个值,无论是原子值(数字、整数、字符)、类似列表(包括data.frame)还是更复杂的值。对于这些,单组()s(如您所知)用于一次调用。

然而,有时函数调用会返回一个function。例如,如果我们查看?scales::label_percent,我们可以向下滚动到

Value:

     All 'label_()' functions return a "labelling" function, i.e. a
     function that takes a vector 'x' and returns a character vector of
     'length(x)' giving a label for each input value.
Run Code Online (Sandbox Code Playgroud)

让我们一步步来看:

Value:

     All 'label_()' functions return a "labelling" function, i.e. a
     function that takes a vector 'x' and returns a character vector of
     'length(x)' giving a label for each input value.
Run Code Online (Sandbox Code Playgroud)

第一次调用scales::label_percent()返回一个函数。然后我们可以使用带有任意数量参数的函数。

如果您不想将返回的函数存储在诸如 之类的变量中fun,则可以通过在第一组()s 后面加上另一组括号来立即使用它。

fun <- scales::label_percent()
fun
# function (x) 
# {
#     number(x, accuracy = accuracy, scale = scale, prefix = prefix, 
#         suffix = suffix, big.mark = big.mark, decimal.mark = decimal.mark, 
#         style_positive = style_positive, style_negative = style_negative, 
#         scale_cut = scale_cut, trim = trim, ...)
# }
# <bytecode: 0x00000168ee5440e8>
# <environment: 0x00000168ee5501b8>
fun(0.35)
# [1] "35%"
Run Code Online (Sandbox Code Playgroud)

一个相关的问题是“为什么你想要一个函数返回另一个函数?” 有很多风格上的原因,但就 而言scales::label_*,它们被设计用于需要将选项表示为函数而不是静态值的地方。例如,它可以在 ggplot 代码中使用:通常使用简单的启发式方法方便地放置轴刻度,以确定刻度线的计数、位置和渲染。虽然可以ggplot2::scale_*_manual(values = ...)手动控制它们的数量、位置和外观,但先验地不关心它们的数量或位置通常会更方便,并且在使用分面的情况下,每个分面变量可能会有所不同,所以不能轻易地在静态变量中赋值。在这些情况下,通常最好分配一个给定一些简单参数(例如轴的最小值/最大值)的函数,并且该函数返回一些有意义的内容。

为什么我们不能直接通过呢scales::label_percent?(好问题。)即使您在此处的调用中使用默认值,人们也可能想要更改任何或所有可控的事物,例如:

  • suffix=默认为"%",但也许您想要一个空格,如" %"?
  • decimal.mark=默认为".",但也许您的语言环境更喜欢逗号?

虽然为这些选项的所有组合提供多个函数是可行的,但从长远来看,提供用于创建函数的“模板函数”通常更容易,例如

scales::label_percent()(0.35)
# [1] "35%"
Run Code Online (Sandbox Code Playgroud)

  • 再次精彩的答案! (3认同)
  • 这是一个非常好的答案。你写过任何 R 书籍吗?如果没有,请这样做。如果你来迈阿密,晚餐由我承担。 (2认同)