我怎样才能像使用 . 一样从 rlang 的 .data 中获取数据属性?

How can I get data attributes from rlang's .data like I can with .?

我正在构建一个在 dplyrmutate 中使用的整洁兼容函数,我想在其中传递一个变量以及我正在使用的数据集,并使用来自两者的信息来构建向量。

作为一个基本示例,假设我想要 return 一个字符串,其中包含变量的平均值和数据集中的行数(我知道我可以只取长度 var, 忽略它, 这是一个例子).

library(tidyverse)
library(rlang)

info <- function(var,df = get(".",envir = parent.frame())) {
  paste(mean(var),nrow(df),sep=', ')
}

dat <- data.frame(a = 1:10, i = c(rep(1,5),rep(2,5)))

#Works fine, 'types' contains '5.5, 10'
dat %>% mutate(types = info(a))

好的,到目前为止很棒。但现在也许我希望它能处理分组数据。 var 将仅来自一组,但 . 将是完整的数据集。因此,我将使用 rlang.data 代词,这只是正在处理的数据。

然而,.data. 不同。 . 是数据集,但 .data 只是一个代词,我可以从中使用 .data[[varname]].

提取变量
info2 <- function(var,df = get(".data",envir = parent.frame())) {
  paste(mean(var),nrow(.data),sep=', ')
}

#Doesn't work. nrow(.data) gives blank strings
dat %>% group_by(i) %>% mutate(types = info2(a))

如何从 .data 获得 完整的东西 ?我知道我没有在示例中包含它,但具体来说,我既需要 attr(dat) 中的一些内容,也需要 dat 中的变量中的一些内容,这些内容已针对分组进行了适当的子集化,因此既不恢复为 . 也不只是提取变量并从那里获取东西。

正如上面评论中提到的 Alexis,这是不可能的,因为这不是 .data 的预期用途。但是,既然我已经放弃直接这样做,我已经使用 ..data.

的组合来解决问题
info <- function(var,df = get(".",envir = parent.frame())) {
  #First, get any information you need from .
  fulldatasize <- nrow(df)

  #Then, check if you actually need .data,
  #i.e. the data is grouped and you need a subsample
  if (length(var) < nrow(df)) {
      #If you are, get the list of variables you want from .data, maybe all of them
      namesiwant <- names(df)

      #Get .data
      datapronoun <- get('.data',envir=parent.frame())

      #And remake df using just the subsample
      df <- data.frame(lapply(namesiwant, function(x) datapronoun[[x]]))
      names(df) <- namesiwant
  }

  #Now do whatever you want with the .data data
  groupsize <- nrow(df)

  paste(mean(var),groupsize,fulldatasize,sep=', ')
}

dat <- data.frame(a = 1:10, i = c(rep(1,5),rep(2,5)))

#types contains the within-group mean, then 5, then 10
dat %>% group_by(i) %>% mutate(types = info(a))

这里为什么不使用 length() 而不是 nrow()

dat <- data.frame(a = 1:10, i = c(rep(1,5),rep(2,5)))

info <- function(var) {
  paste(mean(var),length(var),sep=', ')
}
dat %>% group_by(i) %>% mutate(types = info(a))
#> # A tibble: 10 x 3
#> # Groups:   i [2]
#>        a     i types
#>    <int> <dbl> <chr>
#>  1     1     1 3, 5 
#>  2     2     1 3, 5 
#>  3     3     1 3, 5 
#>  4     4     1 3, 5 
#>  5     5     1 3, 5 
#>  6     6     2 8, 5 
#>  7     7     2 8, 5 
#>  8     8     2 8, 5 
#>  9     9     2 8, 5 
#> 10    10     2 8, 5