inSilecoMisc 0.4.0 (part 1/2)

[This article was first published on R-bloggers on inSileco, 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.

inSilecoMisc

inSilecoMisc is an R 📦 I
have been maintaining for four years now. It was originally designed as a
convenient way to share handy functions. Instead of stacking them in my
.Rprofile, I created a package and made it available on GitHub. inSilecoMisc
is therefore a set of miscellaneous functions, just as other R packages (e.g.
Hmisc) but as I frequently change its API,
it is meant to stay in the experimental stage! I like having inSilecoMisc on
GitHub because it gives a large degree of freedom to experiment new ideas, new
functions and the code remains available and easy to install! Despite the “API
instability”, the overall quality of the package is constantly improving (at
least, I hope so 😄). I have even included some of the somewhat more
matured functions in the research compendium of recent manuscripts1.

Over the last month, I made substantial changes throughout the package. I
re-wrote some functions, improved the documentation of others and added new
features. I also changed the way the pkgdown
website is deployed
by
Travis. In what follows, I introduced several functions included in
versions 0.4.0. Note that as inSilecoMisc is on GitHub, an easy way
to install inSilecoMisc is provided by the package
remotes

install.packages("remotes") # if not already installed
remotes::install_github("inSileco/inSilecoMisc")

Once installed, let’s load it!

library("inSilecoMisc")
packageVersion("inSilecoMisc")
#R> [1] '0.4.0'

adjustStrings

As an ecologist, I frequently work with multiple datasets, and I often need to
name/rename a bunch of files. One function I often use to do so is sprintf():

sprintf("file_%02d", 1:10)
#R>  [1] "file_01" "file_02" "file_03" "file_04" "file_05" "file_06" "file_07"
#R>  [8] "file_08" "file_09" "file_10"

I originally designed
adjustStrings()
to adjust the number of 0 to a string in a similar fashion:

adjustStrings(1:10, n = 2)
#R>  [1] "01" "02" "03" "04" "05" "06" "07" "08" "09" "10"

But I was rapidly interested in having a more flexible function. So, I added several parameters to do that!
In the last version of inSilecoMisc, adjustStrings() have 5 arguments:

  1. x: the input character vector to be adjusted;
  2. n: the number of characters to be added or used to determine the length of output strings;
  3. extra: the character(s) to be added (0 is the default value);
  4. align: the string alignment (“right”, “left” or “center”);
  5. add: whether n should be the constraint or a number of characters to be added (a constraint by default).

By default, adjustStrings() uses n as a constrain for the length of the output strings. so if use n = 4 instead of n = 2 in the first example, all
elements of the output vector will have 4 characters:

adjustStrings(1:10, n = 4)
#R>  [1] "0001" "0002" "0003" "0004" "0005" "0006" "0007" "0008" "0009" "0010"

Add I change the value of extra to specify the replacement character(s) to be used :

adjustStrings(1:10, n = 4, extra = 1)
#R>  [1] "1111" "1112" "1113" "1114" "1115" "1116" "1117" "1118" "1119" "1110"
adjustStrings(1:10, n = 4, extra = "a")
#R>  [1] "aaa1" "aaa2" "aaa3" "aaa4" "aaa5" "aaa6" "aaa7" "aaa8" "aaa9" "aa10"
adjustStrings(1:10, n = 4, extra = "-")
#R>  [1] "---1" "---2" "---3" "---4" "---5" "---6" "---7" "---8" "---9" "--10"
adjustStrings(1:10, n = 4, extra = "ab")
#R>  [1] "aba1" "aba2" "aba3" "aba4" "aba5" "aba6" "aba7" "aba8" "aba9" "ab10"

With align, I can choose where extra characters are added:

adjustStrings(1:10, n = 4, extra = "-", align = "right") # default
#R>  [1] "---1" "---2" "---3" "---4" "---5" "---6" "---7" "---8" "---9" "--10"
adjustStrings(1:10, n = 4, extra = "-", align = "left")
#R>  [1] "1---" "2---" "3---" "4---" "5---" "6---" "7---" "8---" "9---" "10--"
adjustStrings(1:10, n = 4, extra = "-", align = "center")
#R>  [1] "--1-" "--2-" "--3-" "--4-" "--5-" "--6-" "--7-" "--8-" "--9-" "-10-"

Also, if add = TRUE, then exactly n extra characters are added:

adjustStrings(1:10, n = 4, extra = "-", align = "right", add = TRUE)
#R>  [1] "----1"  "----2"  "----3"  "----4"  "----5"  "----6"  "----7"  "----8" 
#R>  [9] "----9"  "----10"
adjustStrings(1:10, n = 4, extra = "-", align = "left", add = TRUE)
#R>  [1] "1----"  "2----"  "3----"  "4----"  "5----"  "6----"  "7----"  "8----" 
#R>  [9] "9----"  "10----"
adjustStrings(1:10, n = 4, extra = "-", align = "center", add = TRUE)
#R>  [1] "--1--"  "--2--"  "--3--"  "--4--"  "--5--"  "--6--"  "--7--"  "--8--" 
#R>  [9] "--9--"  "--10--"

Note that in this last case, lengths of output character strings may differ!
One last remark about how adjustStrings() works when add = FALSE: for a given string, there are 3 scenarios :

  1. the string to be adjusted has more characters than n; in this case, the string is simply cut off:

adjustStrings("ABCD", n = 2, extra = "efgh")
#R> [1] "AB"

  1. the string has more characters but the number of character for the adjustment is smaller than the number of extra’s character; in this case, extra is cut off:

adjustStrings("ABCD", n = 6, extra = "efgh")
#R> [1] "efABCD"

  1. finally, when extra is too short to adjust the string according to n, extra is repeated:

adjustStrings("ABCD", n = 14, extra = "efgh")
#R> [1] "efghefghefABCD"

These combinations give flexibility to the user. One application of the
adjustStrings() function comes when running a long script. In such situation,
it is convenient to create recognizable code section to ease the navigation
across long output!

report <- function(title, symbol = "#") {
  cat(adjustStrings(title, 70, symbol, align = "center"), "\n")
}
report(" part 1 ")
report(" Solving ODE ", "~")
report(" Last but not least! ", "=")
#R> ############################### part 1 ############################### 
#R> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Solving ODE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
#R> ========================= Last but not least! ========================

keepWords

keepWords() allows the user to select words based on their position in
character strings. Before using it, I would like to introduce loremIpsum()
that generates placeholder texts.
Note that there are several functions to generate placeholder texts available
elsewhere. For instance, stringi has
stri_rand_lipsum()
and UsingR includes
lorem()
.
By default, this loremIpsum() function returns two paragraphs of text:

cat(loremIpsum())
#R> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
#R>   tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
#R>   quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
#R>   consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
#R>   cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
#R>   proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
#R> 
#R>   Curabitur pretium tincidunt lacus. Nulla gravida orci a odio. Nullam varius,
#R>   turpis et commodo pharetra, est eros bibendum elit, nec luctus magna felis
#R>   sollicitudin mauris. Integer in mauris eu nibh euismod gravida. Duis ac tellus
#R>   et risus vulputate vehicula. Donec lobortis risus a elit. Etiam tempor. Ut
#R>   ullamcorper, ligula eu tempor congue, eros est euismod turpis, id tincidunt
#R>   sapien risus a quam. Maecenas fermentum consequat mi. Donec fermentum.
#R>   Pellentesque malesuada nulla a mi. Duis sapien sem, aliquet nec, commodo eget,
#R>   consequat quis, neque. Aliquam faucibus, elit ut dictum aliquet, felis nisl
#R>   adipiscing sapien, sed malesuada diam lacus eget erat. Cras mollis scelerisque
#R>   nunc. Nullam arcu. Aliquam consequat. Curabitur augue lorem, dapibus quis,
#R>   laoreet et, pretium ac, nisi. Aenean magna nisl, mollis quis, molestie eu,
#R>   feugiat in, orci. In hac habitasse platea dictumst.
#R>

but it also allows the user to set the number of words of the character string returned:

loremIpsum(18)
#R> [1] "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod\n tempor incididunt ut labore et dolore magna"

Note the escape characters (\n)! Now let’s focus on keepWords(). Assuming I
want to extract the second word in both sentences loremIpsum(18) and be or not to be, all I have to do is:

keepWords(c(loremIpsum(18), "be or not to be"), 2)
#R> [1] "ipsum" "or"

and if I am interested in extracting specific word positions, I can pass a numerical vector:

keepWords(c(loremIpsum(18), "be or not to be"), c(1:4, 12:16))
#R> [1] "Lorem ipsum dolor sit tempor incididunt ut labore et"
#R> [2] "be or not to NA NA NA NA NA"

As you may have noted, NAs are added when the position selected does not
exist. This behavior could be useful but also annoying! Fortunately, an
argument allows to remove NAs.

keepWords(c(loremIpsum(18), "be or not to be"), c(1:4, 12:16), na.rm = TRUE)
#R> [1] "Lorem ipsum dolor sit tempor incididunt ut labore et"
#R> [2] "be or not to"

Also, collapse allows the user to change the character used to separate words:

keepWords(loremIpsum(18), c(1:6, 14:18), collapse = "-")
#R> [1] "Lorem-ipsum-dolor-sit-amet-consectetur-ut-labore-et-dolore-magna"

and if collapse = NULL then list will be returned including a vector of the selected words per input string:

keepWords(c(loremIpsum(18), "be or not to be"), c(2:3), collapse = NULL)
#R> [[1]]
#R> [1] "ipsum" "dolor"
#R> 
#R> [[2]]
#R> [1] "or"  "not"

Note that all punctuation characters will be removed. This can be changed by tweaking argument split_words!

There are two other functions that work similarly: keepLetters() and keepInitials(). The former selects letters instead of words.

keepLetters(loremIpsum(18), c(1:6, 14:18))
#R> [1] "Loremiorsit"
keepLetters(loremIpsum(18), c(1:6, 14:18), collapse = "-")
#R> [1] "L-o-r-e-m-i-o-r-s-i-t"
keepLetters(loremIpsum(18), c(1:6, 14:18), collapse = NULL)
#R> [[1]]
#R>  [1] "L" "o" "r" "e" "m" "i" "o" "r" "s" "i" "t"

while the latter extracts initials

keepInitials("National Basketball Association")
#R> [1] "NBA"
keepInitials("National Basketball Association", "-")
#R> [1] "N"

Note that if the input character vector has a mixture of lower and upper case, so will the output

keepInitials("National basketball association")
#R> [1] "Nba"

if this annoys you, base functions upper() and lower() come in handy!

keepInitials(tolower("National basketball association"))
#R> [1] "nba"
keepInitials(toupper("National basketball association"))
#R> [1] "NBA"

Concluding remarks

In this post, I focused on inSileco’s functions that manipulate character
strings (all of them call
str_split()
at some point). If you are interested in learning more about strings
manipulations, you should checkout the ebook “Handling Strings with
R”
by Gaston
Sanchez
. There are also various blog posts on
this topic (for instance
http://uc-r.github.io or on
data-flair) and, obviously, the documentation of packages that do such manipulations (e.g. stringi).

This concludes the first part of this post, additional features of the
inSilecoMisc package will be introduced the second part of this post 🎉!

Session info

sessionInfo()
#R> R version 4.0.0 (2020-04-24)
#R> Platform: x86_64-pc-linux-gnu (64-bit)
#R> Running under: Ubuntu 20.04 LTS
#R> 
#R> Matrix products: default
#R> BLAS/LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.8.so
#R> 
#R> locale:
#R>  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
#R>  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
#R>  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C             
#R>  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
#R>  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
#R> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
#R> 
#R> attached base packages:
#R> [1] stats     graphics  grDevices utils     datasets  methods   base     
#R> 
#R> other attached packages:
#R> [1] inSilecoMisc_0.4.0     inSilecoRef_0.0.1.9000
#R> 
#R> loaded via a namespace (and not attached):
#R>  [1] Rcpp_1.0.4        pillar_1.4.3      compiler_4.0.0    later_1.0.0      
#R>  [5] plyr_1.8.6        tools_4.0.0       digest_0.6.25     lifecycle_0.2.0  
#R>  [9] tibble_3.0.0      lubridate_1.7.4   jsonlite_1.6.1    evaluate_0.14    
#R> [13] rcrossref_1.0.0   pkgconfig_2.0.3   rlang_0.4.5       bibtex_0.4.2.2   
#R> [17] cli_2.0.2         shiny_1.4.0.2     crul_0.9.0        curl_4.3         
#R> [21] yaml_2.2.1        blogdown_0.18     xfun_0.12         fastmap_1.0.1    
#R> [25] RefManageR_1.2.12 httr_1.4.1        stringr_1.4.0     dplyr_0.8.5      
#R> [29] xml2_1.3.1        knitr_1.28        vctrs_0.2.4       htmlwidgets_1.5.1
#R> [33] tidyselect_1.0.0  DT_0.13           glue_1.4.0        httpcode_0.2.0   
#R> [37] R6_2.4.1          fansi_0.4.1       rmarkdown_2.1     bookdown_0.18    
#R> [41] purrr_0.3.3       magrittr_1.5      ellipsis_0.3.0    promises_1.1.0   
#R> [45] htmltools_0.4.0   assertthat_0.2.1  mime_0.9          xtable_1.8-4     
#R> [49] httpuv_1.5.2      stringi_1.4.6     miniUI_0.1.1.1    crayon_1.3.4


  1. see the following
    repositories:
    HomogenFishOntario and
    coocc_not_inter.

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

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.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)