How to add a progress bar to a package function in r - r

I am running a moving window function from the package landscapemetrics. This seems to take some time as the raster is quite big. It would be really helpful to have a progress bar or something similar. How can I code something like this without having a for loop or a self-coded function to begin with? I don't know how to provide an example raster, but here is my code:
my.raster <- raster('forest2_nonforest1_min_extent.tif')
#specify window size
moving_window <- matrix(1,nrow=5,ncol=5)
#moving window analysis
tt <- window_lsm(my.raster,
window = moving_window,
level= "landscape",
what = c("lsm_l_ed"))
I need to have a visualization of the progress for the last function (#moving window analysis)

The function window_lsm() uses raster::focal() internally, which doesn't provide a progress bar itself. So without writing your own loop/moving window function I think this won't be possible, unfortunately.
As already mentioned above, the progress argument in window_lsm() refers to layers and metrics only, but not the moving window.

Not familiar with this package, but window_lsm() has an argument progress which will "print progress report" when TRUE.
Otherwise, to the best of my knowledge it's not possible to implement a true progress bar without any kind of iteration / loop. The one other option I see would be to look at the source of window_lsm(); find the outermost loop (if there is one); define your own local version of the function; and insert a progress bar incremented inside the loop (e.g. using the progress package). (Obviously, you wouldn't want to redistribute this without looking into the licensing / discussing with package devs.)
I guess another option would be to somehow develop an estimate of how long the operation might take, e.g., based on the size of your raster, then run a countdown timer in a parallel process? My hunch is this would be hard to implement and not especially accurate.

Related

How to prevent a plot from the past repainting?

Is there a way to prevent a plot that has already appeared from erasing itself shortly after? I'm using pinescript on TradingView and an indicator sometimes does this. I'm aware it is due to security() and lookahead_on, and that repainting in the code should be avoided entirely, but I'd like to experiment with just making sure the plot itself is permanent when it appears, irrespective as to whether the code tells it to erase itself.
Thanks for any help
It's hard to tell without seeing your code.
For security() you can use the following function:
f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on)
For other cases, you can use the barstate.isconfirmed built-in variable together with your other conditions that feeds the plot(). barstate.isconfirmed will be true with the last update of the bar. So, in that caase, the price action would be confirmed.

Progress bar for single, long command (not a loop) in R

I can see some very nice progress bars in R, for example using the progress package or cat()function
The problem is, these only work with long tasks that are performed incrementally, like loops or multiple commands
Is there a way to have a progress bar that doesn't rely on a loop or sequence of operations, and can simply work for a single, long command?
Note
If I could somehow start the timed progress bar in progress package simultaneously with the main operation, that would also solve the issue (but I'm not sure if it's possible?). Here is a timed progress bar for reference
library(progress)
pb <- progress_bar$new(total = 100)
for (i in 1:100) {
pb$tick()
Sys.sleep(1 / 100)
}
Also note
An example of a time consuming (single) command could be as simple as Sys.sleep(20). The actual use case I have is extracting a large JSON object from an API which takes 10 - 30 seconds depending on connection speed etc

bupaR - changing the metric the process map displays?

I've gone through their documentation (here & here), but I don't see a simple way to tweak this. For instance if I wanted the lines to show time spent in minutes and the bubbles to show the distinct # of cases that appeared there instead of absolute/relative frequency - ex: when looking at incident case data.
Do I have to render the process map myself via DiagrammeR? I was trying to find some a similar example in DiagrammeR but I couldn't find much.
Any tips / good examples I could reference? I suppose its because this is quite new. I did find this older article but I wasn't sure how to connect the dots. Is it worth continuing my analysis in bupaR or should I leverage a different process map generating library?
This wasn't possible so far, but it is now due to a recent change on the github repo. You can now have frequencies on nodes and times on arrow (or vice versa).
What you do is, first install the github version of the package:
devtools::install_github("gertjanssenswillen/processmapr")
then, use the new type_edges and type_nodes arguments, in the same way as you would use the type argument before.
data %>% process_map(type_nodes = frequency(value = "absolute_case"), type_edges = performance(FUN = mean, units = "min"))

A better way to have R wait on NetLogo with RNetLogo package

I have a model that has some commands that seem to take longer than R is willing to wait. I have resorted to inserting a Sys.sleep in R. Is there a better way? There are not any natural reporters to use a dowhile.
For example, I will call a command where my turtles go through a process of claiming territory and moving around.
RNetLogo::NLCommand("count_and_claim", nl.obj = nl_obj)
This does not take a very long time, but is not quick either. When I ask for the territory held by one of the breeds
RNetLogo::NLGetPatches(sounderTerritoryStrength, patchset="patches", as.matrix=TRUE,
as.data.frame=FALSE, patches.by.row=FALSE,
as.vector=FALSE, nl.obj = nl_obj))
The object will not be found if I do not insert a Sys.sleep(2) in R.
Error in lapply(patch.var, function(x) { :
object 'sounderTerritoryStrength' not found
Is there a better way to avoid this problem than using Sys.sleep()?

How to check that a user-defined function works in r?

THis is probably a very silly question, but how can I check if a function written by myself will work or not?
I'm writing a not very simple function involving many other functions and loops and was wondering if there are any ways to check for errors/bugs, or simply just check if the function will work. Do I just create a simple fake data frame and test on it?
As suggested by other users in the comment, I have added the part of the function that I have written. So basically I have a data frame with good and bad data, and bad data are marked with flags. I want to write a function that allows me to produce plots as usual (with the flag points) when user sets flag.option to 1, and remove the flag points from the plot when user sets flag.option to 0.
AIR.plot <- function(mydata, flag.option) {
if (flag.option == 1) {
par(mfrow(2,1))
conc <- tapply(mydata$CO2, format(mydata$date, "%Y-%m-%d %T"), mean)
dates <- seq(mydata$date[1], mydata$date[nrow(mydata(mydata))], length = nrow(conc))
plot(dates, conc,
type = "p",
col = "blue",
xlab = "day",
ylab = "CO2"), error = function(e) plot.new(type = "n")
barplot(mydata$lines, horiz = TRUE, col = c("red", "blue")) # this is just a small bar plot on the bottom that specifies which sample-taking line (red or blue) is providing the samples
} else if (flag.option == 0) {
# I haven't figured out how to write this part yet but essentially I want to remove all
# of the rows with flags on
}
}
Thanks in advance, I'm not an experienced R user yet so please help me.
Before we (meaning, at my workplace) release any code to our production environment we run through a series of testing procedures to make sure our code behaves the way we want it to. It usually involves several people with different perspectives on the code.
Ideally, such verification should start before you write any code. Some questions you should be able to answer are:
What should the code do?
What inputs should it accept? (including type, ranges, etc)
What should the output look like?
How will it handle missing values?
How will it handle NULL values?
How will it handle zero-length values?
If you prepare a list of requirements and write your documentation before you begin writing any code, the probability of success goes up pretty quickly. Naturally, as you begin writing your code, you may find that your requirements need to be adjusted, or the function arguments need to be modified. That's okay, but document those changes when they happen.
While you are writing your function, use a package like assertthat or checkmate to write as many argument checks as you need in your code. Some of the best, most reliable code where I work consists of about 100 lines of argument checks and 3-4 lines of what the code actually is intended to do. It may seem like overkill, but you prevent a lot of problems from bad inputs that you never intended for users to provide.
When you've finished writing your function, you should at this point have a list of requirements and clearly documented expectations of your arguments. This is where you make use of the testthat package.
Write tests that verify all of the requirements you wrote are met.
Write tests that verify you can no put in unintended inputs and get the results you want.
Write tests that verify you get the output you intended on your test data.
Write tests that test any edge cases you can think of.
It can take a long time to write all of these tests, but once it is done, any further development is easier to check since anything that violates your existing requirements should fail the test.
That being said, I'm really bad at following this process in my own work. I have the tendency to write code, then document what I did. But the best code I've written has been where I've planned it out conceptually, wrote my documentation, coded, and then tested against my documentation.
As #antoine-sac pointed out in the links, some things cannot be checked programmatically; for example, if your function terminates.
Looking at it pragmatically, have a look at the packages assertthat and testthat. assertthat will help you insert checks of results "in between", testthat is for writing proper tests. Yes, the usual way of writing tests is creating a small test example including test data.

Resources