r-在data.table中使用rlang双大括号{{



问题

rlang包中的{{}}运算符使将列名作为函数参数(也称为Quasiquote)传递变得非常容易。我知道rlang是用来与tidyverse配合使用的,但有没有办法在data.table中使用{{}}

{{}}与dplyr的预期用途

test_dplyr <- function(dt, col1, col2){

temp <- dt %>%
group_by( {{col2}} ) %>%
summarise(test = mean( {{col1}} ))
return(temp)
}
test_dplyr(dt=iris, col1=Sepal.Length, col2=Species)
> # A tibble: 3 x 2
>   Species     test
>   <fct>      <dbl>
> 1 setosa      5.01
> 2 versicolor  5.94
> 3 virginica   6.59

尝试将{{}}与data.table一起使用失败

这是理想情况下我想做的,但它返回一个ERROR。

test_dt2 <- function(dt, col1, col2){

data.table::setDT(dt)
temp <- dt[, .( test = mean({{col1}})), by = {{col2}} ] )
return(temp)
}
# error
test_dt2(dt=iris, col1= Sepal.Length, col2= Species)
# and error
test_dt2(dt=iris, col1= 'Sepal.Length', col2= 'Species')

rlang与data.table的替代使用

这里有一种将rlangdata.table结合使用的替代方法。这里有两个不相容性,一个是对每个列名变量rlang::ensym(),另一个是必须在rlang::injec()内部调用data.table操作。

test_dt <- function(dt, col1, col2){

# eval colnames
col1 <- rlang::ensym(col1)
col2 <- rlang::ensym(col2)

data.table::setDT(dt)
temp <- rlang::inject( dt[, .( test = mean(!!col1)), by = !!col2] )
return(temp)
}
test_dt(dt=iris, col1='Sepal.Length', col2='Species')
>       Species  test
> 1:     setosa 5.006
> 2: versicolor 5.936
> 3:  virginica 6.588

我认为您不想将rlang与data.table一起使用。data.table本身已经有了更方便的功能。还建议不要在这里使用setDT,因为这会导致更改dt的副作用。

library(data.table)
test_dt <- function(dt, col1, col2) {
as.data.table(dt)[, .( test = mean(.SD[[col1]])), by = c(col2)]
}
test_dt(dt = iris, col1 = 'Sepal.Length', col2 = 'Species')
##       Species  test
## 1:     setosa 5.006
## 2: versicolor 5.936
## 3:  virginica 6.588

这也起作用:

test_dt <- function(dt, col1, col2) {
as.data.table(dt)[, .( test = mean(get(col1))), by = c(col2)]
}
test_dt(dt=iris, col1='Sepal.Length', col2='Species')

相关内容

  • 没有找到相关文章

最新更新