Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get non-zero values from string in R

Tags:

string

r

I have two strings:

x1 = "03011000"
x2 = "13001000"

The strings have an exact overlap in their non-zero characters. I would like to get for every character position the max element. So in this case the result would be:

result = "13011000"

The first character is a 1 because x2 has a 1 at the first position. The fourth character is also a 1 because x1 has a 1 at this position. The way I go about it is the following:

paste0(mapply(pmax, strsplit(x1, ""), strsplit(x2, "")), collapse = "")

But this seems excessive as I have to split every character into its components and compare them. Is there a better approach to this?

like image 317
User2321 Avatar asked Feb 08 '19 14:02

User2321


2 Answers

Using raw comparison:

rawToChar(as.raw(pmax(as.numeric(charToRaw(x1)), as.numeric(charToRaw(x2)))))
# [1] "13011000"

We could wrap it into a function:

foo <- function(x, y){
  mapply(FUN = function(x, y) {
    rawToChar(as.raw(pmax(as.numeric(charToRaw(x)), as.numeric(charToRaw(y)))))
  }, x = x, y = y, USE.NAMES = FALSE)
}

x1 <- "03011000"
x2 <- "13001000"
foo(x1, x2)
# [1] "13011000"

x1 <- c("03011000", "ab", "123")
x2 <- c("13001000", "cd", "212")
foo(x1, x2)
# [1] "13011000" "cd"       "223"     
like image 108
zx8754 Avatar answered Nov 14 '22 01:11

zx8754


The strings have an exact overlap in their non-zero characters.

I assume this means that when both strings are nonzero, they are guaranteed to match?

If so, it is sufficient to find the positions with zeros in one vector and not in the other (with setdiff) and make the string edit:

r <- gregexpr("0", c(x1,x2))
w <- setdiff(r[[1]], r[[2]])
rr <- structure(w, match.length = rep(1L, length(w)), useBytes = TRUE)

x = x1
regmatches(x, rr) <- regmatches(x2, rr)
x
# [1] "13011000"
like image 3
Frank Avatar answered Nov 14 '22 01:11

Frank