hadley / lazyeval Goto Github PK
View Code? Open in Web Editor NEWLazy evaluation: an alternative to non-standard evaluation (NSE) for R
Lazy evaluation: an alternative to non-standard evaluation (NSE) for R
Steps to reproduce:
var <- "something"
f <- function(x) {
force(x)
lazyeval::lazy(x)
}
f(var)
## Error in lazyeval::lazy(p) : use of NULL environment is defunct
e.g.
lazyeval::f_capture()
I thought the env
parameter will be used to evaluate the expression but make_lazy
is receiving environment()
instead of my value of env
. Is it an error or am I missing something?
In order to do, e.g.
var <- "mpg"
dplyr::mutate_(mtcars, list(paste0(var, "2") ~ uq(var) * 2))
Maybe that implies we want
f_list(paste0(var, "2") ~ uq(var) * 2)
to be equivalent to
f_list(mpg2 = ~uq(var) * 2)
i.e. we iterate over a list extracting replacing the name with the evaluated LHS.
And add lazy loading stuff. (Needed for other main use of NSE)
OSX Mavericks & R3.1.1 (originally this cropped up as an export error when I tried to install dev version of dplyr)
devtools::install_github("lazy") # seems to install OK
library(lazy)
Error in FUN(structure(c("make_lazy", "make_lazy_dots"), .Names = c("make_lazy", :
no such symbol make_lazy in package /Library/Frameworks/R.framework/Versions/3.1/Resources/library/lazy/libs/lazy.so
Error: package or namespace load failed for ‘lazy’
# these work as expected
eval(substitute(log(mpg)), mtcars)
eval(substitute(mpg), mtcars)
# these do too
library(lazyeval)
lazy_eval(lazy(log(mpg)), mtcars)
lazy_eval(lazy(mpg), mtcars)
library(ggplot2) # has a data set "mpg"
lazy_eval(lazy(log(mpg)), mtcars)
# this one doesn't
lazy_eval(lazy(mpg), mtcars)
All R data structures are valid components of a LANGSXP and sometimes arise inside formulas after some manipulation. Should f_interp()
work with those?
lang <- f_new(quote(c(1L, 2L, 3L)))
vec <- f_new(c(1L, 2L, 3L))
f_interp(lang)
#> ~c(1L, 2L, 3L)
f_interp(vec)
#> Error in f_interp(vec): `x` must be a call, symbol, or scalar
If you think of code as a tree, what functions do you need to manipulate it? What parallels exist between lazyeval and xml2 + purrr?
Key is having pronouns for explicit scoping (when needed)
my_eval <- function(expr, data, parent = parent.frame()) {
env <- new.env(parent = parent)
env$.data <- data
env$.parent <- parent
eval(expr, env)
}
f_interp()
, f_rhs()
, f_capture()
etc.
From http://adv-r.had.co.nz/Expressions.html and pryr
ast()
quote(expr =)
standardise_call()
make_call()
recurse_call()
wrapper?Create a formula from a promise (needed if want to standardise on formula)
I don't know whether it fits with the package's idea, but maybe this could give a+b
?
library(lazyeval)
f1 <- function(...) lazy_dots(...)
g1 <- function(x) f1(x)
g1(a+b)
If it's not a good idea, what's the best thing to write in the body of g1 so that g1(a+b)
gives a+b
?
Using the latest github versions of lazy and dplyr I am getting the above error when using dplyr::select()
It looks to me like as.lazy_dots
is an exported function, so I am confused why this is happening.
library(dplyr)
mtcars %>% select(hp)
# 'as.lazy_dots' is not an exported object from 'namespace:lazy'
Here is my devtools::session_info()
Session info------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
setting value
version R version 3.1.0 (2014-04-10)
system x86_64, darwin13.1.0
ui X11
language (EN)
collate en_US.UTF-8
tz America/New_York
Packages----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package * version date source
assertthat 0.1 2013-12-06 CRAN (R 3.1.0)
colorspace 1.2.4 2013-09-30 CRAN (R 3.1.0)
DBI 0.3.0 2014-09-03 CRAN (R 3.1.0)
devtools * 1.5.0.9001 2014-09-15 Github (hadley/devtools@8a07be0)
dichromat 2.0.0 2013-01-24 CRAN (R 3.1.0)
digest 0.6.4 2013-12-03 CRAN (R 3.1.0)
dplyr * 0.2.0.9000 2014-09-16 Github (hadley/dplyr@d822e0d)
evaluate 0.5.3 2014-03-29 CRAN (R 3.1.0)
formatR 0.10 2013-10-26 CRAN (R 3.1.0)
ggplot2 * 0.9.3.1 2013-03-02 CRAN (R 3.1.0)
ggvis * 0.3.0.9001 2014-09-16 Github (rstudio/ggvis@aaaf579)
gtable 0.1.2 2012-12-05 CRAN (R 3.1.0)
htmltools 0.2.6 2014-08-29 Github (rstudio/htmltools@e8e627a)
httpuv 1.3.0 2014-04-04 CRAN (R 3.1.0)
httr 0.5.0.9000 2014-09-09 local
knitr 1.6 2014-05-25 CRAN (R 3.1.0)
labeling 0.2 2013-06-20 CRAN (R 3.1.0)
lazy * 0.1 2014-09-16 Github (hadley/lazy@f23581f)
magrittr 1.1.0 2014-05-19 Github (smbache/magrittr@810f47f)
MASS 7.3.31 2014-03-28 CRAN (R 3.1.0)
memoise 0.1 2010-09-03 CRAN (R 3.1.0)
munsell 0.4.2 2013-07-11 CRAN (R 3.1.0)
plyr 1.8.1 2014-02-26 CRAN (R 3.1.0)
proto 0.3.10 2012-12-22 CRAN (R 3.1.0)
R6 2.0 2014-08-19 CRAN (R 3.1.0)
RColorBrewer 1.0.5 2011-06-17 CRAN (R 3.1.0)
Rcpp 0.11.2 2014-06-08 CRAN (R 3.1.0)
RCurl 1.95.4.1 2013-03-06 CRAN (R 3.1.0)
reshape2 1.2.2 2012-12-04 CRAN (R 3.1.0)
RJSONIO 1.0.3 2013-03-28 CRAN (R 3.1.0)
rstudioapi 0.1 2014-03-27 CRAN (R 3.1.0)
scales 0.2.3 2012-12-05 CRAN (R 3.1.0)
setwidth * 1.0.3 2013-01-16 CRAN (R 3.1.0)
shiny 0.10.1.9006 2014-08-29 Github (rstudio/shiny@7d88775)
stringr 0.6.2 2012-12-06 CRAN (R 3.1.0)
vimcom * 1.0.0 2014-07-21 Github (jalvesaq/VimCom@0cc5132)
whisker 0.3.2 2013-04-28 CRAN (R 3.1.0)
xtable 1.7.3 2014-03-06 CRAN (R 3.1.0)
> dplyr::summarise_(mtcars,
mad_hp=lazyeval::interp("mad(hp)",
.values=as.environment("package:stats")))
Error in values[is_lazy] :
object of type 'environment' is not subsettable
Due to the behaviour of deparse
, interp
behaves unexpectedly for long character expressions.
interp("aaaaaaaaaaaaaa + bbbbbbbbbbbbbbb + ccccccccccccccccc + dddddddddddddddd + eeeeeeeeeeeeeee")
# [1] "aaaaaaaaaaaaaa + bbbbbbbbbbbbbbb + ccccccccccccccccc + dddddddddddddddd + "
# [2] " eeeeeeeeeeeeeee"
Pure interpolation for emptyenv()
?
Add uqf()
to insert literal formulas.
See the fix in #22
lazy(date)
returns a lazy object with expression "lazyLoadDBfetch(c(250834L, 107L), datafile, compressed, envhook)" and not date. Is there a way around this?
This is the cause of this dplyr issue: tidyverse/dplyr#1427
str( lazyeval:::as.lazy( NA_character_ )$expr )
#> logi NA
str( lazyeval:::as.lazy( NA_integer_ )$expr )
#> int NA
str( lazyeval:::as.lazy( NA_real_ )$expr )
#> num NA
I couldn't find mention of this in the docs, and thought it was a bit confusing. I turned this into the simplest example I could come up with:
eg1 <- function(...){
lazy_eval(lazy_dots(...))
}
eg2 <- function(...){
print(names(list(...)))
lazy_eval(lazy_dots(...))
}
eg1(from = 2*pi)
$from
[1] 6.283185
eg2(from = 2*pi)
[1] "from"
Error in eval(expr, envir, enclos) : could not find function "*"
in e1, things work as expected, but in eg2, the env for the expression ends up being NULL, so it fails to find *
:
# eg1
$from
<lazy>
expr: 2 * pi
env: <environment: R_GlobalEnv>
attr(,"class")
[1] "lazy_dots"
# eg2:
$from
<lazy>
expr: 2 * pi
env: NULL
attr(,"class")
[1] "lazy_dots"
Apologies if this is a misunderstanding of how ...
works, but I thought I could send those off to multiple functions within a function and doing so wouldn't impact the result of the second one.
The call to microbenchmark is throwing a 'negative execution time' exception, which aborts lazyeval installation:
> devtools::install_github('hadley/lazyeval')
Installing github repo lazyeval/master from hadley
Downloading master.zip from https://github.com/hadley/lazyeval/archive/master.zip
...
* installing the package to build vignettes
* creating vignettes ...Warning: running command '"C:/PROGRA~1/R/R-31~1.1/bin/x64/Rscript" --vanilla --default-packages= -e "tools::buildVignettes(dir = '.', tangle = TRUE)"' had status 1
ERROR
Quitting from lines 19-26 (benchmark.Rmd)
Error: processing vignette 'benchmark.Rmd' failed with diagnostics:
Measured negative execution time! Please investigate and/or contact the package author.
Execution halted
Error: Command failed (1)
> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Rcpp_0.11.2 devtools_1.5
loaded via a namespace (and not attached):
[1] digest_0.6.4 evaluate_0.5.5 formatR_1.0 httr_0.4 knitr_1.6 memoise_0.2.1 parallel_3.1.1 RCurl_1.95-4.3
[9] stringr_0.6.2 tools_3.1.1 whisker_0.3-2
For strings, calls, atomics, etc.
Because the data
argument in lazy_eval()
allows you to look in a data.frame/list before the environment, it is not always the case that you'd like lazy to follow promises all the way until they can be evaluated in the global environment.
For example, if I wanted to change the select()
function to accept named arguments, lazy()
will follow the promises too far. Setting .follow_symbols = F
doesn't work either, because it checks the names from the function in data, not what the user input.
library(lazyeval)
library(dplyr)
# dplyr::select
# select <- function(.data, ...) {
# select_(.data, .dots = lazyeval::lazy_dots(...))
# }
# direct translation of lazy_dots() to lazy()
select2 <- function(.data, group1, group2) {
out1 <- select_(.data, .dots = lazy(group1))
out2 <- select_(.data, .dots = lazy(group2))
list(out1, out2)
}
select3 <- function(.data, group1, group2) {
out1 <- select_(.data, .dots = lazy(group1, .follow_symbols = F))
out2 <- select_(.data, .dots = lazy(group2, .follow_symbols = F))
list(out1, out2)
}
# select2 fails when a variable name is technically a promise
# (for example if it's a function in another package)
data.frame(x = 1, order = 2) %>% select2(x, order)
#> Error in lazy(group2) : Promise has already been forced
# select3 doesn't do what I want either
data.frame(x = 1, order = 2) %>% select3(x, order)
#> Error in eval(expr, envir, enclos) : object 'x' not found
But if we could control the number of times that promises are followed, then we could do this:
select4 <- function(.data, group1, group2) {
out1 <- select_(.data, .dots = lazy(group1, .n = 1))
out2 <- select_(.data, .dots = lazy(group2, .n = 1))
list(out1, out2)
}
data.frame(x = 1, order = 2) %>% select4(x, order)
I know that this is related to #30, but that pull request didn't fix my examples. I'll submit a rough PR that has .n, and maybe the two can be combined.
The following error occurs when I install via devtools
:
> devtools::install_github("hadley/lazyeval")
Installing github repo lazyeval/master from hadley
Downloading master.zip from https://github.com/hadley/lazyeval/archive/master.zip
Installing package from C:\Users\trinker\AppData\Local\Temp\RtmpodEpLh/master.zip
Installing lazyeval
"C:/R/R-devel/bin/i386/R" --vanilla CMD build \
"C:\Users\trinker\AppData\Local\Temp\RtmpodEpLh\devtools20382bdc738e\lazyeval-master" \
--no-manual --no-resave-data
* checking for file 'C:\Users\trinker\AppData\Local\Temp\RtmpodEpLh\devtools20382bdc738e\lazyeval-master/DESCRIPTION' ... OK
* preparing 'lazyeval':
* checking DESCRIPTION meta-information ... OK
* cleaning src
* installing the package to build vignettes
* creating vignettes ...Warning: running command '"C:/R/R-devel/bin/i386/Rscript" --vanilla --default-packages= -e "tools::buildVignettes(dir = '.', tangle = TRUE)"' had status 1
ERROR
Quitting from lines 19-26 (benchmark.Rmd)
Error: processing vignette 'benchmark.Rmd' failed with diagnostics:
Measured negative execution time! Please investigate and/or contact the package author.
Execution halted
Error: Command failed (1)
Session Info
> sessionInfo()
R Under development (unstable) (2014-09-23 r66669)
Platform: i386-w64-mingw32/i386 (32-bit)
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] graphics grDevices datasets utils grid stats methods base
other attached packages:
[1] Rcpp_0.11.3 shortcut_1.0.0 plotflow_1.0 gridExtra_0.9.1 qdap_2.2.0 RColorBrewer_1.0-5 qdapRegex_0.1.3
[8] qdapDictionaries_1.0.3 reports_0.3.0 qdapTools_1.0.3 pacman_0.2.0 scales_0.2.4 acc.roxygen2_0.1.1 devtools_1.5
[15] roxygen2_4.0.2 ggplot2_0.9.3.1.99
loaded via a namespace (and not attached):
[1] assertthat_0.1 BH_1.54.0-4 bibtex_0.3-6 chron_2.3-45 colorspace_1.2-4 data.table_1.9.2 digest_0.6.4 dplyr_0.2
[9] evaluate_0.5.5 formatR_1.0 gdata_2.13.3 gender_0.4.1 gtable_0.1.2 gtools_3.4.1 httr_0.5 igraph_0.7.1
[17] jsonlite_0.9.11 knitcitations_1.0-1 knitr_1.6 lubridate_1.3.3 markdown_0.7.4 MASS_7.3-34 memoise_0.2.1 munsell_0.4.2
[25] NLP_0.1-5 openNLP_0.2-3 openNLPdata_1.5.3-1 parallel_3.2.0 plotrix_3.5-7 plyr_1.8.1 proto_0.3-10 RCurl_1.95-4.3
[33] RefManageR_0.8.34 reshape2_1.4 rJava_0.9-6 RJSONIO_1.3-0 slam_0.1-32 slidify_0.3.52 stringr_0.6.2 tm_0.6
[41] tools_3.2.0 venneuler_1.1-0 whisker_0.3-2 wordcloud_2.5 XLConnect_0.2-9 XLConnectJars_0.2-9 xlsx_0.5.7 xlsxjars_0.6.1
[49] XML_3.98-1.1 yaml_2.1.13
The package installs but lazyeval.so can't be loaded - see transcript below
> devtools::install_github("hadley/lazyeval")
Downloading github repo hadley/lazyeval@master
Installing lazyeval
'/usr/lib/R/bin/R' --vanilla CMD INSTALL '/tmp/RtmpXZu4Zr/devtools36c7384feb9e/hadley-lazyeval-00fa790' \
--library='/home/hottwaj/R/x86_64-pc-linux-gnu-library/3.1' --install-tests
* installing *source* package ‘lazyeval’ ...
** libs
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c lazy.c -o lazy.o
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c make_call.c -o make_call.o
gcc -std=gnu99 -I/usr/share/R/include -DNDEBUG -fpic -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c promises.c -o promises.o
gcc -std=gnu99 -shared -Wl,-Bsymbolic-functions -Wl,-z,relro -o lazyeval.so lazy.o make_call.o promises.o -L/usr/lib/R/lib -lR
installing to /home/hottwaj/R/x86_64-pc-linux-gnu-library/3.1/lazyeval/libs
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
unable to load shared object '/home/hottwaj/R/x86_64-pc-linux-gnu-library/3.1/lazyeval/libs/lazyeval.so':
/home/hottwaj/R/x86_64-pc-linux-gnu-library/3.1/lazyeval/libs/lazyeval.so: undefined symbol: Rf_mkPROMISE
Error: loading failed
Execution halted
ERROR: loading failed
* removing ‘/home/hottwaj/R/x86_64-pc-linux-gnu-library/3.1/lazyeval’
Error: Command failed (1)
Hi looking to install in order to load ggvis eval
restarted RStudio
devtools::install_github("hadley/lazyeval")
Warning: running command 'make -f "C:/PROGRA~1/R/R-31~1.1/etc/x64/Makeconf" -f "C:/PROGRA~1/R/R-31~1.1/share/make/winshlib.mk" SHLIB="lazyeval.dll" WIN=64 TCLBIN=64 OBJECTS="lazy.o"' had status 127
ERROR: compilation failed for package 'lazyeval'
* removing 'C:/Users/pssguy/AppData/Local/Temp/RtmpEp2bCp/Rinst19f05e46acc/lazyeval'
-----------------------------------
ERROR: package installation failed
Error: Command failed (1)
sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale:
[1] LC_COLLATE=English_Canada.1252 LC_CTYPE=English_Canada.1252
[3] LC_MONETARY=English_Canada.1252 LC_NUMERIC=C
[5] LC_TIME=English_Canada.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] devtools_1.5 digest_0.6.4 evaluate_0.5.5 formatR_1.0 httr_0.5
[6] knitr_1.6 memoise_0.2.1 parallel_3.1.1 RCurl_1.95-4.3 stringr_0.6.2
[11] tools_3.1.1 whisker_0.3-2
Are these differences intentional?
foo <- function(x) {
lx <- lazyeval::f_capture(x)
c(label = expr_label(x), text = expr_text(x))
}
foo(x)
## label text
## "`x`" "x"
foo(a ~ b)
## label text
## "`a ~ b`" "a ~ b"
If so, perhaps this could be documented to explain why.
Since they don't actually help
Should have second argument used as default environment when promise already forced.
Filing this based on an email discussion. Details and an example are here: https://gist.github.com/karthik/ff8b44d41e16c84b5837#file-quantiles-r-L15-L16
The issue is that it isn't currently possible to pass on additional arguments to functions inside interp.
f <- function(x) {
x + 1
lazyeval::lazy(x)
}
xyz <- 10
f(xyz)
I'm wondering if there is a good reason not to allow data
to be an environment in lazy_eval()
.
Changing
if (!is.null(data)) {
eval(x$expr, data, x$env)
}
to
if (!is.null(data)) {
eval(x$expr, as.list(data), x$env)
}
should not change anything when data
is a list or a data frame but would make it easy to write functions with a data
argument that defaults to parent.env()
(or anything else that reasonably coerces to a list, I guess.)
For (( ))
and ({ })
It would be nice if this worked:
foo <- function(x, data = parent.frame()) {
lx <- lazyeval::f_capture(x)
lazyeval::f_eval(lx, data)
}
foo(a ~ b)
## Error: Do not know how to find data associated with `x`
foo(5)
## Error: Do not know how to find data associated with `x`
Currently:
f_capture(NULL)
## Error: `rhs` must be a language object
Would it be better to return NULL in this case? That might make it easier to program with in functions that use NULL as a default value. I'm currently doing this:
y_lazy <- if (!is.null(y)) lazyeval::f_capture(y) else NULL
It seems that there is already a package on CRAN with the name "lazy".
This has the potential for confusion/problems.
Also needs to work when things to interp are formulas, e.g.
x <- 10
y <- 10
interp(~ .(x) + .(y))
interp(~ x + y, list(x = ~10, y = ~z))
# Bit awkward with operator precedence :/
interp(~ lm(f, data = mpg), list(f = ~ (y ~ x)))
``
As suggested by krlmlr on http://stackoverflow.com/questions/36137399/lazy-and-lazy-eval-from-lazyeval-package I am adding this as an issue.
If I write:
> lazy_1 <- lazy(x+y, env = globalenv())
> lazy_1
<lazy>
expr: x + y
env: <environment: R_GlobalEnv>
> x <- 1 ; y <- 2
> lazy_eval(lazy_1)
[1] 3
This makes sense to me as globalenv() is the environment in which to evaluate the expression as states by ?lazy
But when I write:
> rm(list = ls())
> env_2 <- new.env()
> env_2$x <- 6
> env_2$y <- 3
> lazy_2 <- lazy(x+y, env = env_2)
> lazy_2
<lazy>
expr: x + y
env: <environment: R_GlobalEnv>
> lazy_eval(lazy_2)
Error in eval(expr, envir, enclos) : object 'x' not found
I would expect the same behavior from globalenv and env_2
Note that if I force the structure of lazy_2 as I assumed it should have been:
> lazy_2$env <- env_2
> lazy_eval(lazy_2)
[1] 9
everything works fine.
interp( a ~ b, a = 5, b=7)
## 5 ~ b
It seems like it would be good to check the length of the formula and either do substitution on both sides or emit an error about an unsupported formula shape.
Documentation also includes nothing about the required shape of formulas:
An object to modify: can be a call, name, formula, lazy, or a string.
Perhaps just adding
if (length(`_obj`) == 3L) `_obj`[[3]] <- substitute_(`_obj`[[3]], values)
would be an easy and sane fix.
f_eval()
"evaluates" a formula. It was designed thinking the the formula came from f_capture()
and so only had a rhs. But formulas in general also have a lhs, so it would be nice to be able to evaluate that as well.
Here are two possible solutions:
lhs_eval()
and rhs_eval()
. rhs_eval <- f_eval
is essentially an alias for the current function that only evaluates the rhs. lhs_eval()
is analogous.f_eval()
to indicate which side is being evaluated. Something likef_eval <- function(x, data = NULL, side = c("right", "left", "both")) {
}
where "both" would return a list of length 2. Or
f_eval <- function(x, data = NULL, right = TRUE) { # or left = FALSE
}
It would be nice if expr_text()
and expr_label()
could work on formulas as well as promises, or if similar functions were made for operating on the formulas.
This comes from tidyverse/dplyr#705 :
> lazy_dots(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) %>% auto_name() %>% names
[1] "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
> lazy_dots(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA) %>% auto_name() %>% names
[1] "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA..."
With some reasonable defaults. I am thinking about something like this:
subset2_ <- function(df, condition) {
condition <- as.lazy(condition, parent.frame())
r <- lazy_eval(condition, df)
r <- r & !is.na(r)
df[r, , drop = FALSE]
}
subset2 <- make_nse(subset2_, condition)
and this would create subset2
as in the vignette:
subset2 <- function(df, condition) {
condition <- lazy(condition)
subset2_(df, condition)
}
Not that it is a lot of work to write subset2
by hand, but this way you could be sure that subset2
and subset2_
are in sync.
From @rpruim: Many of the functions in the package are named foo_bar()
. Sometimes foo
indicates what type of object is returned (f_capture()
returns a formula) and sometimes foo
indicates what sort of thing must be the input (f_eval()
operates on a formula). That seems a little bit confusing. If expr
here is supposed to indicate that the first argument is a promise, perhaps f_capture()
should be expr_capture()
, or perhaps all of these should be p_*
(p for promise).
Related to tidyverse/dplyr#866.
I understand this encoding issue comes from R's default implementation of combining list, but hope there'd be a way to resolve this.
> dots1 <- lazy_dots(한=1)
> names(dots1)
[1] "한"
> Encoding(names(dots1))
[1] "unknown"
> dots2 <- all_dots(dots1, 한=2)
> Encoding(names(dots2))
[1] "UTF-8" "UTF-8"
So it can be used with non-data frame things.
The print output can be confusing since it differs from the object structure:
x <- lazyeval::as.lazy(~foo)
x
# <lazy>
# code: foo
# env: <environment: 0x7fae6e3a3428>
str(x)
# List of 2
# $ expr: symbol foo
# $ env :<environment: 0x7fae6e3a3428>
# - attr(*, "class")= chr "lazy"
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.