Я пытаюсь научиться писать на R предметно-ориентированный язык с rlang
. Это всего лишь мини-пример, чтобы понять, как работают синтаксический анализ и операции.
Скажем, у меня есть следующие данные:
> top <- seq(2,10,2)
> bottom <- rep(2,length(top))
> times <- rep(10,length(top))
> df <- tibble::tibble(top,bottom,times)
> df
top bottom times
<dbl> <dbl> <dbl>
1 2.00 2.00 10.0
2 4.00 2.00 10.0
3 6.00 2.00 10.0
4 8.00 2.00 10.0
5 10.0 2.00 10.0
Мне нужен предметный язык, в котором используются следующие примеры
1.
df_result1 <- divi(top | bottom ~ times, df)
2.
df_result2 <- divi(top | bottom ~ 1, df)
И производит следующее:
1.
> df_result1
# A tibble: 5 x 4
top bottom times result
<dbl> <dbl> <dbl> <dbl>
1 2.00 2.00 10.0 10.0
2 4.00 2.00 10.0 20.0
3 6.00 2.00 10.0 30.0
4 8.00 2.00 10.0 40.0
5 10.0 2.00 10.0 50.0
2.
> df_result2
# A tibble: 1 x 1
result
<dbl>
1 3.00
В dplyr
жаргоне функции:
1.
df_result1 <- df %>% mutate(result = (top/bottom)*times)
2.
df_result2 <- df %>% summarise(result = mean((top/bottom)))
Обновлять
После некоторой специальной работы я пришел к следующему для одного из случаев. Это, вероятно, технически некрасиво, но свою работу выполняет.
divi <- function(form, data){
data %>% mutate(result=eval_tidy(f_lhs(f_lhs(form)))/
eval_tidy(f_rhs(f_lhs(form)))*
eval_tidy(f_rhs(form)))
}
divi(top | bottom ~ times, df)
top bottom times ressult
<dbl> <dbl> <dbl> <dbl>
1 2 2 10 10
2 4 2 10 20
3 6 2 10 30
4 8 2 10 40
5 10 2 10 50