假设我想从涉及另一个表的列的表达式创建一个新表。这很简单:
library(rlang)
library(purrr)
from_exprs = function(tb, ...) {
quos(...) %>%
map_dfc(~ eval_tidy(., tb))
}
示例:
> tb = data.frame(year = 2001:2005, month = 1, names = letters[1:5])
> tb
year month names
1 2001 1 a
2 2002 1 b
3 2003 1 c
4 2004 1 d
5 2005 1 e
> from_exprs(tb, year + month, toupper(names))
# A tibble: 5 x 2
V1 V2
<dbl> <chr>
1 2002 A
2 2003 B
3 2004 C
4 2005 D
5 2006 E
现在我需要评估不是来自...
而是来自列表的表达式。我想要一个新函数from_exprs2()
,以便像
from_exprs2(tb,
Y = list(year + month, year - month),
Z = list(toupper(names), tolower(names))
)
返回两个表,每个表对应一个表。以前的策略不起作用:
> from_exprs2 = function(tb, Y, Z) {
+ tb_y = quos(Y) %>%
+ map_dfc(~ eval_tidy(., tb))
+ tb_z = quos(Z) %>%
+ map_dfc(~ eval_tidy(., tb))
+ list(tb_y, tb_z)
+ }
> from_exprs(tb, Y = list(year + month, year - month), Z = list(toupper(names), tolower(names)))
Show Traceback
Rerun with Debug
Error in cbind_all(x) : Not compatible with STRSXP: [type=NULL].
答案 0 :(得分:1)
比我想象的要容易。使用enquo()
捕获表达式,使用eval_tidy()
作为列表进行评估。之后,只需将其转换为数据框。
from_exprs2 = function(tb, Y, Z) {
tb_y = enquo(Y) %>%
eval_tidy(tb) %>%
as.data.frame
tb_z = enquo(Z) %>%
eval_tidy(tb) %>%
as.data.frame
list(tb_y, tb_z)
}
from_exprs2(tb,
Y = list(year + month, year - month),
Z = list(toupper(names), tolower(names)))
输出:
[[1]]
c.2002..2003..2004..2005..2006. c.2000..2001..2002..2003..2004.
1 2002 2000
2 2003 2001
3 2004 2002
4 2005 2003
5 2006 2004
[[2]]
c..A....B....C....D....E.. c..a....b....c....d....e..
1 A a
2 B b
3 C c
4 D d
5 E e