I am trying to institute a  workflow to answer SO questions using knitr and
render_markdown(strict = T ) to format my answers and / questions. 
Recently I was trying to run profiling on some code using profr and due to the implementation of knitr, the profiling picks up all the calls to evaluate etc that underpin knitr
For example
Not in knitr
If I run in plain R
library(profr)
quantile_ex <- profr({Sys.sleep(1); example(quantile, setRNG = TRUE)}, 0.01)
quantile_ex
##                      f level time start  end  leaf source
## 9       Sys.sleep     1 0.64  0.01 0.65  TRUE   base
## 10        example     1 0.05  0.65 0.70 FALSE  utils
## 11   index.search     2 0.01  0.65 0.66 FALSE   <NA>
## 12    <Anonymous>     2 0.02  0.66 0.68 FALSE   <NA>
## 13         source     2 0.01  0.68 0.69 FALSE   base
## 14         unlink     2 0.01  0.69 0.70  TRUE   base
## 15    file.exists     3 0.01  0.65 0.66  TRUE   base
## 16     prepare_Rd     3 0.01  0.66 0.67 FALSE   <NA>
## 17            of0     3 0.01  0.67 0.68 FALSE   <NA>
## 18           file     3 0.01  0.68 0.69  TRUE   base
## 19   .getHelpFile     4 0.01  0.66 0.67 FALSE   <NA>
## 20            of1     4 0.01  0.67 0.68 FALSE   <NA>
## 21    <Anonymous>     5 0.01  0.66 0.67 FALSE   <NA>
## 22     WriteLines     5 0.01  0.67 0.68 FALSE   <NA>
## 23 lazyLoadDBexec     6 0.01  0.66 0.67 FALSE   base
## 24     writeLines     6 0.01  0.67 0.68 FALSE   base
## 25            fun     7 0.01  0.66 0.67 FALSE   <NA>
## 26         paste0     7 0.01  0.67 0.68 FALSE   base
## 27       basename     8 0.01  0.66 0.67  TRUE   base
## 28             wr     8 0.01  0.67 0.68 FALSE   <NA>
## 29         paste0     9 0.01  0.67 0.68 FALSE   base
## 30        strwrap    10 0.01  0.67 0.68 FALSE   base
## 31         lapply    11 0.01  0.67 0.68 FALSE   base
## 32       strsplit    12 0.01  0.67 0.68  TRUE   base
Using knitr + profr
render_markdown(strict = T)
library(profr)
quantile_ex <- profr({
    Sys.sleep(1)
    example(quantile, setRNG = TRUE)
}, 0.01)
quantile_ex
##                      f level time start  end  leaf source
## 8          <Anonymous>     1 0.80  0.00 0.80 FALSE   <NA>
## 9  process_group.block     2 0.80  0.00 0.80 FALSE   <NA>
## 10          call_block     3 0.80  0.00 0.80 FALSE   <NA>
## 11          block_exec     4 0.80  0.00 0.80 FALSE   <NA>
## 12            evaluate     5 0.80  0.00 0.80 FALSE   <NA>
## 13              unlist     6 0.80  0.00 0.80 FALSE   base
## 14              mapply     7 0.80  0.00 0.80 FALSE   base
## 15         <Anonymous>     8 0.80  0.00 0.80 FALSE   <NA>
## 16                 try     9 0.80  0.00 0.80 FALSE   base
## 17            tryCatch    10 0.80  0.00 0.80 FALSE   base
## 18        tryCatchList    11 0.80  0.00 0.80 FALSE   <NA>
## 19         tryCatchOne    12 0.80  0.00 0.80 FALSE   <NA>
## 20          doTryCatch    13 0.80  0.00 0.80 FALSE   <NA>
## 21 withCallingHandlers    14 0.80  0.00 0.80 FALSE   base
## 22         withVisible    15 0.80  0.00 0.80 FALSE   base
## 23                eval    16 0.80  0.00 0.80 FALSE   base
## 24                eval    17 0.80  0.00 0.80 FALSE   base
## 25               profr    18 0.80  0.00 0.80 FALSE  profr
## 26                 try    19 0.80  0.00 0.80 FALSE   base
## 27            tryCatch    20 0.80  0.00 0.80 FALSE   base
## 28        tryCatchList    21 0.80  0.00 0.80 FALSE   <NA>
## 29         tryCatchOne    22 0.80  0.00 0.80 FALSE   <NA>
## 30          doTryCatch    23 0.80  0.00 0.80 FALSE   <NA>
## 31               force    24 0.80  0.00 0.80 FALSE   base
## 32           Sys.sleep    25 0.77  0.00 0.77  TRUE   base
## 33             example    25 0.03  0.77 0.80 FALSE  utils
## 34         <Anonymous>    26 0.02  0.77 0.79 FALSE   <NA>
## 35              source    26 0.01  0.79 0.80 FALSE   base
## 36          prepare_Rd    27 0.01  0.77 0.78 FALSE   <NA>
## 37              render    27 0.01  0.78 0.79 FALSE   <NA>
## 38         withVisible    27 0.01  0.79 0.80 FALSE   base
## 39        .getHelpFile    28 0.01  0.77 0.78 FALSE   <NA>
## 40                 of0    28 0.01  0.78 0.79 FALSE   <NA>
## 41                eval    28 0.01  0.79 0.80 FALSE   base
## 42         <Anonymous>    29 0.01  0.77 0.78 FALSE   <NA>
## 43                 of1    29 0.01  0.78 0.79 FALSE   <NA>
## 44                eval    29 0.01  0.79 0.80 FALSE   base
## 45      lazyLoadDBexec    30 0.01  0.77 0.78 FALSE   base
## 46          WriteLines    30 0.01  0.78 0.79 FALSE   <NA>
## 47            quantile    30 0.01  0.79 0.80 FALSE  stats
## 48                 fun    31 0.01  0.77 0.78 FALSE   <NA>
## 49          writeLines    31 0.01  0.78 0.79  TRUE   base
## 50    quantile.default    31 0.01  0.79 0.80 FALSE  stats
## 51               fetch    32 0.01  0.77 0.78 FALSE   <NA>
## 52               paste    32 0.01  0.79 0.80  TRUE   base
## 53         <Anonymous>    33 0.01  0.77 0.78 FALSE   <NA>
## 54       existsInFrame    34 0.01  0.77 0.78  TRUE   <NA>
using knitr + Rprof + profr::parse_rprof
tmp <- tempfile()
Rprof(tmp, interval = 0.01)
try(force(quantile_ex <- profr({
    Sys.sleep(1)
    example(quantile, setRNG = TRUE)
}, 0.01)))
Rprof(NULL)
parsed <- parse_rprof(tmp, interval = 0.01)
## Error: invalid 'envir' argument
parse_rprof won't run due to environment issues
knitr + Rprof + summaryRprof
Using the utils::summaryRprof  will read and summarize
summaryRprof(tmp)
## $by.self
##       self.time self.pct total.time total.pct
## Rprof      0.01      100       0.01       100
## 
## $by.total
##                     total.time total.pct self.time self.pct
## Rprof                     0.01       100      0.01      100
## <Anonymous>               0.01       100      0.00        0
## block_exec                0.01       100      0.00        0
## call_block                0.01       100      0.00        0
## doTryCatch                0.01       100      0.00        0
## eval                      0.01       100      0.00        0
## evaluate                  0.01       100      0.00        0
## knit                      0.01       100      0.00        0
## mapply                    0.01       100      0.00        0
## process_file              0.01       100      0.00        0
## process_group.block       0.01       100      0.00        0
## try                       0.01       100      0.00        0
## tryCatch                  0.01       100      0.00        0
## tryCatchList              0.01       100      0.00        0
## tryCatchOne               0.01       100      0.00        0
## unlist                    0.01       100      0.00        0
## withCallingHandlers       0.01       100      0.00        0
## withVisible               0.01       100      0.00        0
## 
## $sample.interval
## [1] 0.01
## 
## $sampling.time
## [1] 0.01
## 
It doesn't seem to actually profile the code that was run, only the knitr / evaluate details.
Question and possible solution
My current work flow is to just run profiling outside knitr, but the automatic formatting (commenting out output with ##) I find really useful.
Has anyone come across a neat solution to this, or is it something to take up with the package developers?
My current idea is to rewrite parse_rprof to limit itself to calls above the first call to force (not the default level 7)
Example rewrite of profr
Here is a rewrite of profr that almost works
library(profr)
profr <- function(expr, interval = 0.02, quiet = TRUE) {
    tmp <- tempfile()
    on.exit(unlink(tmp))
    on.exit(unlink("Rprof.out"), add = T)
    if (quiet) {
        tc <- textConnection(NULL, "w")
        sink(tc)
        on.exit(sink(), add = TRUE)
        on.exit(close(tc), add = TRUE)
    }
    Rprof(tmp, append = TRUE, interval = interval)
    try(force(expr))
    Rprof(NULL)
    parsed <- parse_rprof(tmp, interval)
    which_force <- min(which(parsed$f == "force"))
    parsed <- parsed[parsed$level > parsed$level[which_force], ]
    parsed$level <- parsed$level - parsed$level[which_force]
    parsed
}
quantile_ex <- profr({
    Sys.sleep(1)
    example(quantile, setRNG = TRUE)
}, 0.01)
quantile_ex
##                 f level time start  end  leaf source
## 32      Sys.sleep    NA 0.90  0.00 0.90  TRUE   base
## 33        example    NA 0.03  0.90 0.93 FALSE  utils
## 34    <Anonymous>    NA 0.03  0.90 0.93 FALSE   <NA>
## 35     prepare_Rd    NA 0.01  0.90 0.91 FALSE   <NA>
## 36         render    NA 0.02  0.91 0.93 FALSE   <NA>
## 37   .getHelpFile    NA 0.01  0.90 0.91 FALSE   <NA>
## 38           %in%    NA 0.01  0.91 0.92  TRUE   base
## 39            of0    NA 0.01  0.92 0.93 FALSE   <NA>
## 40    <Anonymous>    NA 0.01  0.90 0.91 FALSE   <NA>
## 41            of1    NA 0.01  0.92 0.93 FALSE   <NA>
## 42 lazyLoadDBexec    NA 0.01  0.90 0.91 FALSE   base
## 43     WriteLines    NA 0.01  0.92 0.93 FALSE   <NA>
## 44            fun    NA 0.01  0.90 0.91 FALSE   <NA>
## 45     writeLines    NA 0.01  0.92 0.93 FALSE   base
## 46          fetch    NA 0.01  0.90 0.91  TRUE   <NA>
## 47         paste0    NA 0.01  0.92 0.93 FALSE   base
## 48          remap    NA 0.01  0.92 0.93 FALSE   <NA>
## 49           psub    NA 0.01  0.92 0.93  TRUE   <NA>
The results, are however not the same as from plain R
 
     
  
    