I have the following data to which I am trying to as 1 to the last section of numbers split by a -
. My data is as follows;
dat
"4-3" "60-0 2-5" "10-1 3-2" "20-2 3-0" "3-0" "20-5 3-0"
What I am trying to archive, here we are separately adding 1 to the last number and 1 to the second last number;
dat1
"5-3" "60-0 3-5" "10-1 4-2" "20-2 4-0" "4-0" "20-5 4-0"
dat2
"4-4" "60-0 2-6" "10-1 3-3" "20-2 3-1" "3-1" "20-5 3-1"
I think it might be possible to split the data out using a gsub(), although this could be tricky as my data varies in length between 1 set of numbers and 2, my other issue is that if I use a gsub I'm then unable to add (as far as im aware). My theory would be something like identify the last number and add 1, then identify the second last number and add 1
1) gsubfn gsubfn
is like gsub
except that the replacement argument can be a function and, as here, it can optionally be expressed using a compact formula notation. The capture groups in the regular expression are passed to the function and the free variables in the body are assigned to them in order of occurrence. The output of the function then replaces the portion matched by the regular expression.
library(gsubfn)
res1 <- gsubfn("(\\d+)(-\\d+)$", ~ paste0(as.numeric(x) + 1, y), dat)
identical(res1, dat1)
## [1] TRUE
res2 <- gsubfn("(\\d+)$", ~ as.numeric(x) + 1, dat)
identical(res2, dat2)
## [1] TRUE
2) Base R Uinsg only base R define plus1
to take one component of dat
, split it into a numeric vector num
increment the element k
from the end (k = 1 means last, k = 2 means second last) by 1 and then paste it back togehter. Finally split the input by non-digits and apply plus1
.
plus1 <- function(x, k, num = as.numeric(x))
replace(num, length(num) - k + 1, tail(num, k)[1] + 1) |>
matrix(2) |>
apply(2, paste, collapse = "-") |>
paste(collapse = " ")
base1 <- sapply(strsplit(dat, "\\D+"), plus1, k = 2)
identical(base1, dat1)
## [1] TRUE
base2 <- sapply(strsplit(dat, "\\D+"), plus1, k = 1)
identical(base2, dat2)
## [1] TRUE
dat <- c("4-3", "60-0 2-5", "10-1 3-2", "20-2 3-0", "3-0", "20-5 3-0")
dat1 <- c("5-3", "60-0 3-5", "10-1 4-2", "20-2 4-0", "4-0", "20-5 4-0")
dat2 <- c("4-4", "60-0 2-6", "10-1 3-3", "20-2 3-1", "3-1", "20-5 3-1")