Site icon R-bloggers

Readable code with base R (part 2)

[This article was first published on R some blog, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Combine startsWith and endsWith with R’s pipe

In my first post, startsWith and endsWith were presented. In combination with R’s pipe operator, we can improve the readability even further.

w <- "Hello World!"

w |> startsWith("Hell")
[1] TRUE
w |> endsWith("!")
[1] TRUE

Proceeding with the example of the initial post, let’s see this in context of control flow.

tell_file_type <- function(filename)
{
    if (filename |> endsWith("txt"))
        print("A text file.")
    
    excel_endings <- c("xlsx", "xls")
    if (any(filename |> endsWith(excel_endings)))
        print("An Excel file.")
    
}
tell_file_type("A.xlsx")
[1] "An Excel file."

%in% and %not in%

The %in% operator is commonly used. To improve the readability of something like

existing_names <- c("Lisa", "Bob")
name <- "Peter"
hasNewName = !(name %in% existing_names)

you can always define your own operators.

`%not in%` <- Negate(`%in%`)

hasNewName = name %not in% existing_names

Obviously, the readability also depends on the choice of proper variable names. My general take on this: don’t shy away from longish variable names, if it improves code readability.

In this context, it is often useful to assign boolean values to variables. For example, instead of

if (abs_error < 1e-8) {
    # ...
}

you should do

hasConverged <- abs_error < 1e-8

if (hasConverged) {
    # ...
}

That is, it is ok to add redundancies in your code if it improves readability.

Sometimes, it is not immediately clear from the naming of base R functions, what they do. Of course, you are free to redefine them with a proper name.

equals_pattern = function(x, pattern, ...) grepl(pattern, x, ...)

x <- "Peter"

x |> equals_pattern("^P")
[1] TRUE

Lastly, let’s combine all of the above.

x |> equals_pattern("^P") && 
x |> startsWith("z")      &&
x %not in% existing_names 
[1] FALSE

That’s it for now. Let me know in the comments how you think about this topic or maybe you have another good example of readable code.

To leave a comment for the author, please follow the link and comment on their blog: R some blog.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.