Skip to content

Commit

Permalink
version 0.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
MB4511 authored and cran-robot committed Jun 21, 2021
1 parent 60a4178 commit 295547b
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 40 deletions.
12 changes: 5 additions & 7 deletions DESCRIPTION
@@ -1,7 +1,7 @@
Package: getDTeval
Title: Translating Coding Statements using get() and eval() for
Improved Run-Time Coding Efficiency
Version: 0.0.1
Version: 0.0.2
Authors@R: c(
person("David", "Shilane", , "david.shilane@columbia.edu", c("aut")),
person("Mayur","Bansal", , "mb4511@columbia.edu", c("ctb","cre")),
Expand All @@ -14,19 +14,17 @@ Description: The getDTeval() function facilitates the translation of the origina
The function can either provide a translation of the coding statement, directly evaluate the translation to return a coding result, or provide both of these outputs.
License: GPL-3
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.1.1
Suggests: knitr, rmarkdown, dplyr, testthat (>= 2.1.0), covr,
formulaic, devtools
Imports: stats, data.table, microbenchmark, utils
Suggests: knitr, rmarkdown, dplyr, testthat (>= 2.1.0), covr, devtools
Imports: stats, data.table, formulaic, microbenchmark, utils
VignetteBuilder: knitr
NeedsCompilation: no
Packaged: 2020-11-12 02:37:05 UTC; mayurbansal
Packaged: 2021-06-21 06:00:51 UTC; mayurbansal
Author: David Shilane [aut],
Mayur Bansal [ctb, cre],
Anderson Nelson [ctb],
Caffrey Lee [ctb],
Zichen Huang [ctb]
Maintainer: Mayur Bansal <mb4511@columbia.edu>
Repository: CRAN
Date/Publication: 2020-11-18 09:00:06 UTC
Date/Publication: 2021-06-21 06:10:04 UTC
12 changes: 6 additions & 6 deletions MD5
@@ -1,16 +1,16 @@
2d70dc68bd5c90ad2cff636b12336e51 *DESCRIPTION
1e0f73093a442f00cab87711453dd0ee *NAMESPACE
73bc7d88f248cb1da3a1e580f75d44b0 *DESCRIPTION
b193a5fbb3212b4f335cf04223af77f6 *NAMESPACE
b7371fc0a4c0c1d00d271dc95ce397dc *R/benchmark.getDTeval.R
74ae1944a31083690242505f73e3e578 *R/getDTeval.R
8b727e5f4d0c2c55e62bcafdc3a49b22 *R/getDTeval.R
587c9b41c253aef66b8e768a34a36e48 *README.md
050f8528a7bce23c58bc7bd1705fa932 *build/vignette.rds
90949be0ccba305a6d68dff94a81dcee *inst/doc/Introduction_to_getDTeval.R
ba5cb1b68199ad4b6e6325d2a7910f2c *inst/doc/Introduction_to_getDTeval.Rmd
9bc923cebae80f56727d8a9058cfca46 *inst/doc/Introduction_to_getDTeval.html
8a6c09a78d3c65b6cb0bd2270c98f479 *inst/doc/Introduction_to_getDTeval.Rmd
4dc0a4ed6dbef0d25c7b2d87e4a6f3c5 *inst/doc/Introduction_to_getDTeval.html
5b9e8d16fd83b858ad3d8e37a120a09a *man/benchmark.getDTeval.Rd
fd8e25f21811f2de60b89441c8c3a341 *man/function.ending.point.Rd
4c13eb30a97b0e63e90ceb29d719bd30 *man/getDTeval.Rd
b4764f1aa6e5afbdf05a6f62f66d77d7 *man/translate.fn.calls.Rd
fb5792231f530f9175ee012c30c8d85a *tests/testthat.R
2a5b7740d821c45cb03c1e550fad341d *tests/testthat/test-getDteval.R
ba5cb1b68199ad4b6e6325d2a7910f2c *vignettes/Introduction_to_getDTeval.Rmd
8a6c09a78d3c65b6cb0bd2270c98f479 *vignettes/Introduction_to_getDTeval.Rmd
1 change: 1 addition & 0 deletions NAMESPACE
Expand Up @@ -5,6 +5,7 @@ export(function.ending.point)
export(getDTeval)
export(translate.fn.calls)
import(data.table)
import(formulaic)
import(microbenchmark)
import(stats)
import(utils)
34 changes: 19 additions & 15 deletions R/getDTeval.R
Expand Up @@ -26,28 +26,32 @@ function.ending.point <- function(all.chars, beginning.index, ...) {
#' @param function.name Name of the function to be translated to an optimized form. Parameter values should be either 'get(' or 'eval('. 'get(' is set as default
#' @param envir Specify the environment for the required function. .GlobalEnv is set as default
#' @param ... provision for additional arguments
#' @import formulaic
#' @export


translate.fn.calls <- function(the.statement, function.name = "get(", envir = .GlobalEnv, ...){

translate.fn.calls <- function (the.statement, function.name = "get(", envir = .GlobalEnv,
...)
{
fn.chars <- strsplit(x = function.name, split = "")[[1]]
all.chars <- strsplit(x = the.statement, split = "")[[1]]

first.chars <- which(all.chars == fn.chars[1])

the.begin <- first.chars[as.logical(lapply(X = first.chars, FUN = function(x){return(paste(all.chars[x:(x+length(fn.chars)-1)], collapse = "") == function.name)}))]

the.begin <- first.chars[as.logical(lapply(X = first.chars,
FUN = function(x) {
return(paste(all.chars[x:(x + length(fn.chars) -
1)], collapse = "") == function.name)
}))]
len <- length(the.begin)
if(len > 0){
for(i in 1:length(the.begin)){
the.end <- function.ending.point(all.chars = all.chars, beginning.index = the.begin[i], ...)
the.call <- paste(all.chars[the.begin[i]:the.end], collapse = "")
arg <- trimws(x = gsub(pattern = function.name, replacement = "eval(", x = the.call, fixed = TRUE), which = "both")

evaluated.arg <- eval(expr = parse(text = arg), envir = envir)

if(function.name == "eval("){
if (len > 0) {
for (i in 1:length(the.begin)) {
the.end <- function.ending.point(all.chars = all.chars,
beginning.index = the.begin[i], ...)
the.call <- paste(all.chars[the.begin[i]:the.end],
collapse = "")
arg <- trimws(x = gsub(pattern = function.name, replacement = "eval(",
x = the.call, fixed = TRUE), which = "both")
evaluated.arg <- add.backtick(x = eval(expr = parse(text = arg), envir = envir))
if (function.name == "eval(") {
evaluated.arg <- sprintf("'%s'", evaluated.arg)
}
all.chars[the.begin[i]:the.end] <- ""
Expand Down
2 changes: 1 addition & 1 deletion inst/doc/Introduction_to_getDTeval.Rmd
Expand Up @@ -70,7 +70,7 @@ In the second approach, the **get()** and **eval()** functions are used to conve

Programmatic designs with the get() and eval() functions facilitate calculations in functions and in dynamic applications. Even for basic analyses, this design creates greater flexibility for possible changes. If the name of the Age variable were later changed to another value (e.g. Age_Years), the program could be adapted with a simple modification to the age.name variable. Any downstream use of the Age variable through calls of get() or eval() to age.name would automatically adapt to the change.

However, programmatic designs can lead to reduced runtime efficiency. In the case of simple calls to the get() function, the performance can greatly decrease. The following example demonstrates the associated reductions in efficiency in the case of calculating a grouped average.
However, programmatic designs can lead to reduced runtime efficiency. In the case of simple calls to the get() function, the performance can greatly decrease. The following example demonstrates the associated reductions in efficiency in the case of calculating a grouped average.

```{r runtime_comparison}
age.name <- "Age"
Expand Down
20 changes: 10 additions & 10 deletions inst/doc/Introduction_to_getDTeval.html
Expand Up @@ -10,7 +10,7 @@



<meta name="date" content="2020-11-11" />
<meta name="date" content="2021-06-20" />

<title>Introduction to GetDTeval</title>

Expand Down Expand Up @@ -178,7 +178,7 @@


<h1 class="title toc-ignore">Introduction to GetDTeval</h1>
<h4 class="date">2020-11-11</h4>
<h4 class="date">2021-06-20</h4>

</div>

Expand Down Expand Up @@ -224,9 +224,9 @@ <h2>Introduction</h2>
results[, Effect_Median := Programmatic_Median/Classic_Median]
round(x = results, digits = 4)
#&gt; Classic_Mean Classic_Median Programmatic_Mean Programmatic_Median
#&gt; 1: 0.0245 0.0228 0.0747 0.0714
#&gt; 1: 0.0257 0.0241 0.0629 0.0605
#&gt; Effect_Median
#&gt; 1: 3.1311</code></pre>
#&gt; 1: 2.5119</code></pre>
<p>For larger sample sizes and more complex calculations, the effect of programmatic designs can significantly increase the running time complexity.</p>
<p>The <strong>getDTeval</strong> package was designed to overcome the trade-offs between programmatic designs and running time efficiency. The package creates a means of translating calls to get() and eval() into more optimized coding statements. In doing so, the package not only resolves many observed trade-offs between speed and efficiency; it also creates opportunities to expand the areas in which programmatic designs may be used in common coding applications.</p>
</div>
Expand Down Expand Up @@ -416,9 +416,9 @@ <h3>Example 4</h3>
times = 50,
seed = 282)
#&gt; category Min. 1st Qu. Median Mean 3rd Qu. Max.
#&gt; 1: getDTeval statement 0.009714 0.01114 0.01137 0.01233 0.01222 0.03188
#&gt; 2: optimized coding statement 0.009148 0.01070 0.01105 0.01266 0.01195 0.05292
#&gt; 3: original coding statement 0.056749 0.05780 0.05873 0.06339 0.06508 0.11132</code></pre>
#&gt; 1: getDTeval statement 0.008915 0.01036 0.01041 0.01105 0.01052 0.02977
#&gt; 2: optimized coding statement 0.008581 0.01010 0.01036 0.01169 0.01096 0.05176
#&gt; 3: original coding statement 0.045183 0.04851 0.04922 0.05345 0.05330 0.10045</code></pre>
<p>The original coding statement uses calls to get() to generate results with a programmatic design. In the median and average cases, the running time is substantially worse than using the more optimized statement. There is a real trade-off between the flexibility of the programmatic design and the running time performance of directly naming the variables. However, translating the programmatic design's coding statement using getDTeval() produces running times that are quite similar to what is produced while directly using the optimized statements. These results suggest that getDTeval() can effectively eliminate these tradeoffs.</p>
</div>
</div>
Expand Down Expand Up @@ -456,7 +456,7 @@ <h3>Example 5: Using eval() in Calculated Quantities with data.table</h3>
#&gt; 4: West 50.66667
#&gt;
#&gt; $code
#&gt; [1] &quot;dat[, .('Mean Awareness' = mean(Awareness) * 100), keyby = Region]&quot;
#&gt; [1] &quot;dat[, .('`Mean Awareness`' = mean(Awareness) * 100), keyby = Region]&quot;
#&gt;
#&gt; $original.statement
#&gt; [1] &quot;dat[, .(eval(mean.awareness.name) = mean(get(awareness.name)) * 100), keyby = get(region.name)]&quot;</code></pre>
Expand Down Expand Up @@ -484,7 +484,7 @@ <h3>Example 6: Using eval() in Calculated Quantities with dplyr</h3>
#&gt; 4 West 0.507
#&gt;
#&gt; $code
#&gt; [1] &quot;dat %&gt;% group_by(Region) %&gt;% summarize('Mean Awareness'=mean(Awareness,na.rm=T))&quot;
#&gt; [1] &quot;dat %&gt;% group_by(Region) %&gt;% summarize('`Mean Awareness`'=mean(Awareness,na.rm=T))&quot;
#&gt;
#&gt; $original.statement
#&gt; [1] &quot;dat %&gt;% group_by(get(region.name)) %&gt;% summarize(eval(mean.awareness.name)=mean(get(awareness.name),na.rm=T))&quot;</code></pre>
Expand Down Expand Up @@ -541,7 +541,7 @@ <h4>Example 8: Improving Readability of Grouped Calculations in dplyr</h4>
#&gt; 4 West 4.80
#&gt;
#&gt; $code
#&gt; [1] &quot;dat %&gt;% group_by(Region) %&gt;% summarize('Mean Satisfaction' = mean(Satisfaction, na.rm=T))&quot;
#&gt; [1] &quot;dat %&gt;% group_by(Region) %&gt;% summarize('`Mean Satisfaction`' = mean(Satisfaction, na.rm=T))&quot;
#&gt;
#&gt; $original.statement
#&gt; [1] &quot;dat %&gt;% group_by(get(region.name)) %&gt;% summarize(eval(sprintf(\&quot;Mean %s\&quot;, satisfaction.name)) = mean(get(satisfaction.name), na.rm=T))&quot;</code></pre>
Expand Down
2 changes: 1 addition & 1 deletion vignettes/Introduction_to_getDTeval.Rmd
Expand Up @@ -70,7 +70,7 @@ In the second approach, the **get()** and **eval()** functions are used to conve

Programmatic designs with the get() and eval() functions facilitate calculations in functions and in dynamic applications. Even for basic analyses, this design creates greater flexibility for possible changes. If the name of the Age variable were later changed to another value (e.g. Age_Years), the program could be adapted with a simple modification to the age.name variable. Any downstream use of the Age variable through calls of get() or eval() to age.name would automatically adapt to the change.

However, programmatic designs can lead to reduced runtime efficiency. In the case of simple calls to the get() function, the performance can greatly decrease. The following example demonstrates the associated reductions in efficiency in the case of calculating a grouped average.
However, programmatic designs can lead to reduced runtime efficiency. In the case of simple calls to the get() function, the performance can greatly decrease. The following example demonstrates the associated reductions in efficiency in the case of calculating a grouped average.

```{r runtime_comparison}
age.name <- "Age"
Expand Down

0 comments on commit 295547b

Please sign in to comment.