当前位置: 首页 > 知识库问答 >
问题:

dplyr arrange() 在 c() 中处理单个变量,但在函数内计算时不处理 c() 中的多个变量

连时铭
2023-03-14

我在网上找到的关于tidyeval的所有信息都比较旧,并且不是最新版本的tidyverse\dplyr,或者不太适用。

tibble的一个示例是:

df <- tribble(
       ~var1, ~var2, ~var3,
         1,     2,     3,
         4,     5,     6,
         7,     8,     9
        )

我有一个小函数,我写了:

fun <- function(data, select_var, arrange_var) {
   select_var <- enquo(select_var)
   arrange_var <- enquo(arrange_var)

   data %>%
     select(!!select_var) %>%
     arrange(!!arrange_var)
   }

该函数只需选择列,然后按行排列。

当我将参数传递给函数时,它可以很好地处理c()中的单个变量:

fun(df, 
    c(var1,
      var2)),
    c(var2))

然而,当我试图像这样给它传递两个变量时:

    fun(df, 
    c(var1,
      var2)),
    c(var1,
      var2))

我得到以下错误:

Error: incorrect size (282) at position 1, expecting : 141

我能找到的最接近的堆栈响应是:arrange()不识别列名参数,并将变量名向量传递给dplyr中的arrange()

但这两个问题的答案似乎都包含了不推荐的解决方案(例如,arrange_()

这里有一些很棒的信息:Mara Averick的tidyval资源综述

保罗·奥德姆的《以整洁的方式分离和整理杂乱的数据》

当然,我已经深入研究了:tidyeval

然而,他们似乎都没有解决这个怪癖。在度过了一个下午之后,我已经耗尽了我的资源。代码可以在标准的R文件中找到,只是无法在函数中工作,但已经准备好放弃,所以我想看看你们这些优秀的人是否能帮上忙。提前谢谢。

共有1个答案

谢财
2023-03-14

更新 2022/03/17

tidyverse已经进化,这个答案也应该进化。

不再需要 enquo 了!相反,我们将 tidy-select 表达式括在双括号 {{ }} 中

library("tidyverse")

df <- tribble(
  ~var1, ~var2, ~var3,
  1, 2, 3,
  4, 5, 6,
  7, 8, 9
)

fun <- function(data, select_vars, ...) {
  data %>%
    select(
      {{ select_vars }}
    ) %>%
    arrange(
      ...
    )
}


fun(df, c(var1, var2), desc(var2))
#> # A tibble: 3 × 2
#>    var1  var2
#>   <dbl> <dbl>
#> 1     7     8
#> 2     4     5
#> 3     1     2
fun(df, c(var1, var2), var1, var2)
#> # A tibble: 3 × 2
#>    var1  var2
#>   <dbl> <dbl>
#> 1     1     2
#> 2     4     5
#> 3     7     8

我们仍然不能将c()arrangefilter谓词一起使用,因为数据屏蔽不允许这样做。

df %>%
  arrange(
    c(var1, var2)
  )
#> Error in `arrange()`:
#> ! Problem with the implicit `transmute()` step.
#> x Problem while computing `..1 = c(var1, var2)`.
#> x `..1` must be size 3 or 1, not 6.

< sup >由reprex软件包(v2.0.1)于2022-03-17创建

老答案

arrange_var替换为...并指定变量而不将它们包含在c()中使其工作。

library("dplyr")

df <- tribble(
  ~var1, ~var2, ~var3,
  1, 2, 3,
  4, 5, 6,
  7, 8, 9
)

fun <- function(data, select_var, ...) {
  select_var <- enquo(select_var)
  data %>%
    select(!!select_var) %>%
    # You can pass the dots to `arrange` directly
    arrange(...)
}

fun(df, c(var1, var2), var2)
#> # A tibble: 3 x 2
#>    var1  var2
#>   <dbl> <dbl>
#> 1     1     2
#> 2     4     5
#> 3     7     8
fun(df, c(var1, var2), var1, var2)
#> # A tibble: 3 x 2
#>    var1  var2
#>   <dbl> <dbl>
#> 1     1     2
#> 2     4     5
#> 3     7     8

由reprex包(v0.2.1)于2019-03-08创建

事实证明,只有select支持字符串和字符向量。正如文档所说,“这与字符串不明确的其他动词不同。请参阅最后一个示例,了解 dplyr::select

# Two alternatives; both work with `select`.
df %>%
  select(var1, var2)
#> # A tibble: 3 x 2
#>    var1  var2
#>   <dbl> <dbl>
#> 1     1     2
#> 2     4     5
#> 3     7     8
df %>%
  select(c(var1, var2))
#> # A tibble: 3 x 2
#>    var1  var2
#>   <dbl> <dbl>
#> 1     1     2
#> 2     4     5
#> 3     7     8

# `arrange` only works with lists on comma separated unquoted variable names.
df %>%
  arrange(var1, var2)
#> # A tibble: 3 x 3
#>    var1  var2  var3
#>   <dbl> <dbl> <dbl>
#> 1     1     2     3
#> 2     4     5     6
#> 3     7     8     9
df %>%
  arrange(c(var, var2))
#> Error: incorrect size (4) at position 1, expecting : 3

由reprex包(v0.2.1)于2019-03-08创建

 类似资料:
  • 我使用的是OpenGL,但我并不完全满意将每个三角形(或在我的例子中为四边形)的值传递给片段着色器的标准方法,即将它们分配给基本体的每个顶点,并将它们传递给顶点着色器,以推测不必要的插值(除非使用“flat”指令)在片段着色器中(也就是说,每个片段不变化)。 是否有某种方法可以存储每个三角形(或四边形)的值,这些三角形(或四边形)需要在片段着色器中访问,这样就不需要每个顶点的冗余副本?那么,这种方

  • 我是Camunda的新手,没有找到任何教程或参考来解释如何实现以下目标: 当开始一个过程时,我希望用户在发票中添加任意数量的项目。在下一个用户任务中,所有这些项目及其数量都应该打印给批准数据的人。 我还不知道如何在一个过程和它的变量之间建立1:n的关系。我需要为每个项目启动子流程吗?或者我必须使用自定义Java对象吗?如果是这样,我如何从任务列表中将表单元素映射到这样的对象?

  • You can supply a custom function to handle cache files instead of using the built-in method using the $cache_dir. See the custom cache handler function section for details. 你可以提供一个自定义函数来处理缓存文件,而不是通过变量

  • 问题内容: 第一个问题是Value和Manager()。Value有什么区别? 其次,是否可以不使用Value共享整数变量?下面是我的示例代码。我想要的是获取一个整数值而不是Value的字典。我所做的就是在此过程之后全部更改。有没有更简单的方法? 问题答案: 使用时,您会在共享内存中获得一个对象,默认情况下,该对象使用进行同步。使用该对象时,您将得到一个控制服务器进程的对象,该服务器进程允许对象值

  • 当我呈现视图时,是,因为是我这样插入它。 如果我提交表单,我将执行以下处理程序: 所以基本上我总是要添加一个`stopmessage,不管是成功还是失败。 如何检索设置到另一个处理程序中的属性值?用胸腺嘧啶有可能吗? 注意:暂时,我将设置为控制器类的一个字段,并在处理程序周围设置/not null,以便始终能够看到它的值。这是一个解决办法,但似乎不是正确的做法。因为我是个新手,所以我很乐意听到处理

  • 因此,如果我有一个方法,其中一个变量可以是一组不同类的实例,其中只有一些类有一个特定的实例变量,那么我如何在方法中使用这个实例变量,而不会得到